<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      試用Workflow開發WPF應用程序

           研究了半個月的《WF高級程序設計》,我覺得這個框架做的太有價值了,又將WCF和Web服務結合起來了,提高了它的應用領域。工作流使我們能夠輕松地建模系統,實現真正邏輯意義上的人機交互功能。這在游戲開發中特別有用,而且將開發人員從架構的角度來設計程序,提高程序設計的邏輯性和可讀性。由于書上的例子都是在WinForm和控制臺上的,所以我覺得有必要運用到WPF開發中。由于WPF架構與WinForm許多的差異,所以我試著做了一個WPF的隨機選數游戲來體驗一下WPF與WF的結合。

           由于本例子主要目的在于體現一個順序機制,按理說應該是用順序工作流來處理這個機制,考慮到以后的擴展,我選擇了狀態機工作流。我們先來了解一下狀態機工作流,所謂“狀態機工作流”是指一組應用程序狀態以及狀態之間的可能的轉換。每個狀態都可以處理多個外部事件,外部事件能夠觸發器子活動的執行,而自活動又可能包含一個到其他狀態的轉換。

          先來看一下工作流機制:

      圖片3

      一、建立一個空的工作流項目[一個dll]

           1、定義一個公共的接口

            在這個接口中設計了五個事件和一個方法。定義的事件是為了提供給工作流的使用。

      Generic.xaml

            2、實現接口服務的PointSelectService類,這個外部服務類提供一組事件調用方法和一個事件,供宿主使用,相應的代碼如下:

      代碼
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Workflow.Activities;
      using System.Workflow.Runtime;

      namespace SelectGameWorkflow
      {
      /// <summary>
      /// 實現服務接口類
      /// </summary>
      public class PointSelectService:IPointSelect
      {
      #region IPointSelect 成員

      public event EventHandler<System.Workflow.Activities.ExternalDataEventArgs> StartSelect;

      public event EventHandler<System.Workflow.Activities.ExternalDataEventArgs> StopSelect;

      public event EventHandler<System.Workflow.Activities.ExternalDataEventArgs> First;

      public event EventHandler<System.Workflow.Activities.ExternalDataEventArgs> Second;

      public event EventHandler<System.Workflow.Activities.ExternalDataEventArgs> Third;

      public event EventHandler<ExternalDataEventArgs> Completed;

      /// <summary>
      /// 調用宿主的事件
      /// </summary>
      /// <param name="message"></param>
      public void SendMessage(string message)
      {
      if (MessageReceived != null)
      MessageReceived(
      this, new MessageReceivedEventArgs(WorkflowEnvironment.WorkflowInstanceId, message));
      }

      #endregion

      /// <summary>
      ///
      /// 工作流使用的事件
      /// </summary>
      public event EventHandler<MessageReceivedEventArgs> MessageReceived;

      #region 以下定義了一組供宿主使用的方法


      public void OnStartSelect(ExternalDataEventArgs e)
      {
      if (StartSelect != null)
      StartSelect(
      null, e);
      }

      public void OnStopSelect(ExternalDataEventArgs e)
      {
      if (StopSelect != null)
      StopSelect(
      null, e);
      }

      public void OnFirst(ExternalDataEventArgs e)
      {
      if (First != null)
      First(
      null, e);
      }

      public void OnSecond(ExternalDataEventArgs e)
      {
      if (Second != null)
      Second(
      null, e);
      }

      public void OnThird(ExternalDataEventArgs e)
      {
      if (Third != null)
      Third(
      null, e);
      }

      public void OnCompleted(ExternalDataEventArgs e)
      {
      if (Completed != null)
      Completed(
      null, e);
      }
      #endregion

      }

        這里還定義了一個EventArgs的派生類來傳遞服務消息: 

      代碼
      /// <summary>
      /// 把工作流的相應消息發送到本地服務中
      /// </summary>
      [Serializable]
      public class MessageReceivedEventArgs : ExternalDataEventArgs
      {
      public string Message { get; set; }


      /// <summary>
      /// 在構造器中傳遞消息,其中會將工作流的ID傳遞到基類中
      /// </summary>
      /// <param name="instanceId"></param>
      /// <param name="message"></param>
      public MessageReceivedEventArgs(Guid instanceId, string message):base(instanceId )
      {
      this.Message = message;
      }
      }

       3、在剛才的項目中添加一個狀態機工作流:

        這里面定義了一組狀態事件處理,如表所示:

      無標題  
         除了DoneState狀態之外,每個State都有定義了三個活動,按順序分別是:

         handleExternalEventActivity、callExternalMethodActivity、setStateActivity,可以分別設置他們的接口、事件和方法,如圖所示:

         捕獲    整個狀態機的工作流視圖如下:       捕獲1

        現在我們可以重新生成動態庫了,得到SelectGameWorkflow.dll文件

       二、添加一個WPF項目作為工作流的宿主,這個WPF命名為SelectGameWPF,

           1、 先設計界面,效果如下: 

         捕獲3

         相應的XAML代碼如下:

      代碼
      <Window x:Class="SelectGameWPF.Window1"
      xmlns
      ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x
      ="http://schemas.microsoft.com/winfx/2006/xaml"
      Title
      ="碰手氣" Height="300" Width="300" xmlns:my="clr-namespace:C4F.VistaP2P.WPF.Chat;assembly=C4F_P2PWPFControls" Loaded="Window_Loaded">
      <Grid Background="LightBlue" >
      <Grid.RowDefinitions>
      <RowDefinition Height="50"/>
      <RowDefinition/>
      </Grid.RowDefinitions>
      <TextBlock Height="58" Text="{Binding Number}" x:Name="numberText" VerticalAlignment="Top" FontSize="48" HorizontalAlignment="Center" FontFamily="Broadway">
      <TextBlock.OpacityMask>
      <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
      <GradientStop Color="#E5000000" Offset="0"/>
      <GradientStop Color="#99FFFFFF" Offset="1"/>
      </LinearGradientBrush>
      </TextBlock.OpacityMask>
      <TextBlock.Foreground>
      <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
      <GradientStop Color="#FFED7B69" Offset="0"/>
      <GradientStop Color="#CCFFFFFF" Offset="0.385"/>
      <GradientStop Color="#E8E78851" Offset="0.931"/>
      </LinearGradientBrush>
      </TextBlock.Foreground>
      </TextBlock>
      <GroupBox HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="1">
      <GroupBox.Header>
      <TextBlock Text="控制"/>
      </GroupBox.Header>
      <StackPanel Width="100" x:Name="controlButtons">
      <Button x:Name="startBtn" Content="開 始" Height="40" Margin="5,20" Click="startBtn_Click"/>
      <Button x:Name="stopBtn" Content="停 止" Height="40" Margin="5,0,5,20" Click="stopBtn_Click"/>
      </StackPanel>
      </GroupBox>
      <GroupBox x:Name="control" Header="玩家" HorizontalAlignment="Right" VerticalAlignment="Top" Grid.Row="1">
      <StackPanel Width="100" x:Name="playerButtons">
      <Button x:Name="firstBtn" Content="第一個玩家" Height="40" Margin="5,20" Click="firstBtn_Click"/>
      <Button x:Name="secondBtn" Content="第二個玩家" Height="40" Margin="5,0,5,20" Click="secondBtn_Click"/>
      <Button x:Name="thirdBtn" Content="第三個玩家" Height="40" Margin="5,0,5,20" Click="thirdBtn_Click"/>
      </StackPanel>
      </GroupBox>
      <TextBlock Grid.Row="1" Height="23" HorizontalAlignment="Left" Name="textBlock1" Text="{Binding Message}" VerticalAlignment="Bottom" Width="160" />
      </Grid>
      </Window>

       2、添加兩個更新界面的依賴屬性:

      代碼
      #region 定義一個隨機數和消息
      public static readonly DependencyProperty NumberProperty = DependencyProperty.Register("Number", typeof(int), typeof(Window1), new PropertyMetadata(0));
      public static readonly DependencyProperty MessageProperty = DependencyProperty.Register("Message", typeof(string), typeof(Window1), new PropertyMetadata(string.Empty));

      public int Number {
      get { return (int)GetValue(NumberProperty); }
      set { SetValue(NumberProperty, value); }
      }

      public string Message {
      get { return (string)GetValue(MessageProperty); }
      set { SetValue(MessageProperty, value); }
      }
      #endregion

       為了能夠在UI線程中更新視覺元素,我們使用了和WinForm的Invoke異步調用的相同的Dispatcher類的BeginInvoke方法:

      如下所示:

      代碼
      private delegate void UpdateDelegate();

      /// <summary>
      /// 在指定的時間段內產生隨機數
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
      void timer_Tick(object sender, EventArgs e)
      {
      ///將數字呈現到前臺
      UpdateDelegate theDelg = () =>
      {
      Number
      = rand.Next(100);
      };
      Dispatcher.BeginInvoke(theDelg,
      null);
      }

      其他的更新方式如上面所示

        3、接下來調用工作流項目以及將上面的SelectGameService服務加入到運行時:

      代碼
      /// <summary>
      /// 初始化工作流服務
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
      private void Window_Loaded(object sender, RoutedEventArgs e)
      {
      manager
      = new WorkflowRuntimeManager(new WorkflowRuntime());

      //在轉換到新的狀態時發生
      manager.WorkflowRuntime.WorkflowIdled += new EventHandler<WorkflowEventArgs>(WorkflowRuntime_WorkflowIdled);
      AddServices(manager.WorkflowRuntime);
      }

      /// <summary>
      /// 處理Idle事件
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
      void WorkflowRuntime_WorkflowIdled(object sender, WorkflowEventArgs e)
      {
      UpdateDelegate theDelg
      = () =>
      {
      EnableEventButton(
      false);

      //得到內部隊列信息
      ReadOnlyCollection<WorkflowQueueInfo> queueInfoData = instanceWrapper.WorkflowInstance.GetWorkflowQueueData();

      if (queueInfoData != null) {
      foreach (WorkflowQueueInfo info in queueInfoData) {
      EventQueueName eventQueue
      = info.QueueName as EventQueueName;

      if (eventQueue == null)
      break;

      EnableButtonForEvent(eventQueue.MethodName);
      }
      }
      };

      Dispatcher.BeginInvoke(theDelg,
      null);
      }

      /// <summary>
      /// 根據事件名啟用按鈕
      /// </summary>
      /// <param name="p"></param>
      private void EnableButtonForEvent(string eventName)
      {
      var buttons1
      = controlButtons.Children;
      var buttons2
      = playerButtons.Children;

      foreach (Button btn in buttons1) {
      if (btn.Tag.ToString() == eventName)
      btn.IsEnabled
      = true;
      }
      foreach (Button btn in buttons2)
      {
      if (btn.Tag.ToString() == eventName)
      btn.IsEnabled
      = true;
      }
      }

      /// <summary>
      /// 將服務添加到工作流運行時
      /// </summary>
      /// <param name="workflowRuntime"></param>
      private void AddServices(WorkflowRuntime workflowRuntime)
      {
      ExternalDataExchangeService exchangeService
      = new ExternalDataExchangeService();
      workflowRuntime.AddService(exchangeService);

      pointSelectService
      = new PointSelectService();
      pointSelectService.MessageReceived
      += new EventHandler<MessageReceivedEventArgs>(pointSelectService_MessageReceived);
      exchangeService.AddService(pointSelectService);
      }

      void pointSelectService_MessageReceived(object sender, MessageReceivedEventArgs e)
      {
      UpdateDelegate theDelg
      = () =>
      {
      Message
      = e.Message;
      };

      //保存工作流實例標識
      System.Threading.Thread.Sleep(1000);
      timer.Start();
      instanceId
      = e.InstanceId;

      Dispatcher.BeginInvoke(theDelg,
      null);
      }
      }

       4、初始化按鈕狀態和定時器

      代碼
      public Window1()
      {
      InitializeComponent();
      timer
      = new DispatcherTimer();
      timer.Interval
      = new TimeSpan(0, 0, 0, 0, 300);
      timer.Tick
      += new EventHandler(timer_Tick);
      rand
      = new Random();

      //設置按鈕標識
      startBtn.Tag = "StartSelect";
      stopBtn.Tag
      = "StopSelect";
      firstBtn.Tag
      = "First";
      secondBtn.Tag
      = "Second";
      thirdBtn.Tag
      = "Third";

      EnableEventButton(
      false);

      DataContext
      = this;
      }

      /// <summary>
      /// 控制按鈕的狀態
      /// </summary>
      /// <param name="p"></param>
      private void EnableEventButton(bool p)
      {
      stopBtn.IsEnabled
      = p;
      firstBtn.IsEnabled
      = p;
      secondBtn.IsEnabled
      = p;
      thirdBtn.IsEnabled
      = p;
      }

      5、添加所有按鈕的Click事件,其目的是為了調用服務的方法和宿主本身的定時器的,如下所示:

      代碼
      #region Click events

      private void firstBtn_Click(object sender, System.Windows.RoutedEventArgs e)
      {
      // TODO: Add event handler implementation here.
      try
      {
      pointSelectService.OnFirst(GetEventArgs());
      timer.Stop();
      if (Number > temp)
      {
      temp
      = Number;
      tempPlayer
      = "First";
      }
      }
      catch(Exception ex) {
      HandleException(ex);
      }
      }

      private void secondBtn_Click(object sender, System.Windows.RoutedEventArgs e)
      {
      // TODO: Add event handler implementation here.
      try
      {
      pointSelectService.OnSecond(GetEventArgs());
      timer.Stop();

      if (Number > temp)
      {
      temp
      = Number;
      tempPlayer
      = "Second";
      }
      }
      catch (Exception ex) {
      HandleException(ex);
      }
      }

      private void thirdBtn_Click(object sender, System.Windows.RoutedEventArgs e)
      {
      // TODO: Add event handler implementation here.
      try
      {
      pointSelectService.OnThird(GetEventArgs());
      timer.Stop();

      if (Number > temp)
      {
      temp
      = Number;
      tempPlayer
      = "Third";
      }

      if (tempPlayer != string.Empty)
      {
      UpdateDelegate theDelg
      = () =>
      {
      Message
      = tempPlayer + "得到最大數: " + temp.ToString();
      };
      Dispatcher.BeginInvoke(theDelg,
      null);
      }
      }
      catch (Exception ex) {
      HandleException(ex);
      }
      }

      #endregion

        至此,整個工程全部完成,現在在啟動應用程序以后,我們就可以按如開頭的工作流圖的順序依次 :Start-First-Second-Third-Start。

      其實這個程序我們可以演化到多用戶順序執行程序,如網絡麻將、斗地主等互動游戲的結合。

         完整代碼下載:Workflow

      posted @ 2010-08-20 22:29  suyan010203  Views(4991)  Comments(4)    收藏  舉報
      主站蜘蛛池模板: 亚洲精品香蕉一区二区| 91一区二区三区蜜桃臀| 18av千部影片| 亚洲人妻精品一区二区| 日韩一区二区大尺度在线| 2020精品自拍视频曝光| 国产精品一品二区三四区| 国产精品久久久尹人香蕉| 亚洲一区久久蜜臀av| 亚洲综合视频一区二区三区| 欧美www在线观看| 日本污视频在线观看| 日韩av一区二区精品不卡| 亚洲免费的福利片| 国产精品一区二区三区黄| 亚洲国产亚洲国产路线久久| 国产99视频精品免费视频36| 忘忧草在线社区www中国中文| 国产视频一区二区| 成人午夜大片免费看爽爽爽| 免费无码无遮挡裸体视频在线观看| 亚洲精品毛片一区二区| 亚洲天堂男人天堂女人天堂| 国产成人无码午夜视频在线观看| 日韩av天堂综合网久久| 国产丝袜在线精品丝袜不卡| 亚洲另类激情专区小说图片| 国产中文字幕在线一区| 九九热在线免费视频精品| 国产精品一久久香蕉国产线看观看| 成人区人妻精品一区二蜜臀| 国产精品自在拍首页视频| 亚洲人妻精品中文字幕| 又黄又刺激又黄又舒服| 亚洲综合小说另类图片五月天 | 巩留县| 国产羞羞的视频一区二区| 国产超碰无码最新上传| 丽江市| 欧美老少配性行为| 图片区偷拍区小说区五月|