如何实现自定义工作流WF4

 

客户自定义流程
1.xaml页面
 <StackPanel Grid.ColumnSpan="3">
            <Menu VerticalAlignment="Top" Height="25">
                <MenuItem Header="_File">
                    <MenuItem Header="_New" Command="{Binding Path=NewCommand}">

                    </MenuItem>
                    <MenuItem Header="_Open"
                              Command="{Binding Path=OpenCommand}"/>
                    <Separator />
                    <MenuItem Header="_Save"
                              Command="{Binding Path=SaveCommand}"/>
                    <MenuItem Header="Save _As"
                              Command="{Binding Path=SaveAsCommand}"/>
                    <Separator />
                    <MenuItem Header="E_xit"
                              Command="{Binding Path=ExitCommand}"/>
                </MenuItem>
            </Menu>
        </StackPanel>
在最上面的菜单上加上几个基本菜单,新建,打开,保存,另存为,退出。
在后台需要写一个继承自ICommand接口的属性,

        <TabControl HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0,0,5,0" Grid.Row="1" Grid.Column="0">
            <TabItem Header="This Test">
                <ContentControl Content="{Binding ToolboxPanel}"></ContentControl>
            </TabItem>

        </TabControl>
加载左边的工具箱 在后台定义一个obj类型的ToolboxPanel,
        <TabControl HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0,0,0,0" Grid.Row="1" Grid.Column="1">
            <TabItem Header="Desginer">
                <ContentControl Content="{Binding WorkflowDesignerPanel}"></ContentControl>
            </TabItem>
            <TabItem Header="Xaml" GotFocus="TabItemGotFocusRefreshXamlBox">
                <TextBox Name="xmalTextBox" Text="{Binding XAML, Mode=OneWay}" AcceptsReturn="True"  VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" IsReadOnly="True"></TextBox>
            </TabItem>
        </TabControl>
加载中间的设计界面 在后台定义一个object类型的WorkflowDesignerPanel,和一个String 类型的XAML,
定义一个TabItemGotFocusRefreshXamlBox事件,当点XAML的时候触发
        <TabControl HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="5,0,0,0" Grid.Row="1" Grid.Column="2">
            <TabItem Header="Properies">
                <ContentControl Content="{Binding WorkflowPropertyPanel}"></ContentControl>
            </TabItem>
        </TabControl>
加载右边的属性框 定义一个object类型的属性 WorkflowPropertyPanel。

2.初始化页面

创建MainViewModel类,这个类里实现了客户自定义的全部功能
在MainView.xaml.cs里实例化MainViewModel,
 private MainViewModel mainViewModel;
        public MainWindow()
        {
            InitializeComponent();

            mainViewModel = new MainViewModel();
            //this.DataContext = new CommandView();
            this.DataContext = mainViewModel;
        }

2.1首先加载左边工具箱
首先必须在MainviewModel的构造函数里加上
 (new DesignerMetadata()).Register();
这句话的作用是加载控件的外观,否则控件看起来就像一个盒子,具体什么样子都看不到,而且不可用,比如if控件看到的就是一个方块
然后加载需要在工具箱里需要显示的控件的样式
 LoadToolboxIconsForBuiltInActivities();
这里需要加载Microsoft.VisualStudio.Activities.dll控件,这样才可以把控件的样式显示出来,否则看到的控件就是一个齿轮的样子
这个时候左边的工具箱还是看不到任何控件,现在在左边的工具箱里加载控件

在1里面,左边工具箱里绑定的是一个ToolboxPanel属性,所以必须在类里建一个ToolboxPanel属性
public object ToolboxPanel { get; private set; }
这样才可以在WPF的界面加载到内容
然后this.ToolboxPanel = CreateToolbox();
就可以在左边的工具栏里显示出加载的控件了

2.2新建设计区
首先新建一个WorkflowDesigner类型的属性,主要是为了全局使用
  public WorkflowDesigner WorkflowDesignerObj
        {
            get
            {
                return workflowDesigner;
            }
            private set
            {
                workflowDesigner = value;

            note1    this.NotifyChanged("WorkflowDesignerPanel");
             note2   this.NotifyChanged("WorkflowPropertyPanel");
            }
        }

然后创建一个新的设计区
在Page_Load里加载下面函数ExecuteNew方法

   public void ExecuteNew(object parameter)
        {
            WorkflowDesignerObj = new WorkflowDesigner();

            WorkflowDesignerObj.ModelChanged += new EventHandler(workflowDesigner_ModelChanged);

            if (File.Exists(TemplateXaml))
            {
                WorkflowDesignerObj.Load(TemplateXaml);
            }
            else
            {
                WorkflowDesignerObj.Load(new Sequence());
            }

            WorkflowDesignerObj.Flush();
        }
第一 ,实例化workflowDesigner实例,同时创建workflow的设计界面和XML界面,如 note1 和note2。
这里需要注意的是这个类需要继承接口INotifyPropertyChanged。这个接口里有一个事件,public event PropertyChangedEventHandler PropertyChanged;
这个时间会加载页面的设计视图,XML视图和属性视图。
并且还要建3个属性来对应页面上设计区,XAML和属性区绑定的值,这样才会在页面上出现设计区,XML和属性区
  public object WorkflowDesignerPanel
        {
            get
            {
                return this.WorkflowDesignerObj.View;
            }
        }

        /// <summary>
        ///   Gets WorkflowPropertyPanel.
        /// </summary>
        public object WorkflowPropertyPanel
        {
            get
            {
                return this.WorkflowDesignerObj.PropertyInspectorView;
            }
        }
 public string XAML
        {
            get
            {
                if (this.WorkflowDesignerObj.Text != null)
                {
                    this.WorkflowDesignerObj.Flush();
                    return this.WorkflowDesignerObj.Text;
                }

                return null;
            }
        }
第二,WorkflowDesignerObj.ModelChanged += new EventHandler(workflowDesigner_ModelChanged);
在设计图变化的时候更新xml视图
第三,判断是否有模板,如果存在模板就加在模板,否则加载一个顺序流。
第四,刷新设计界面新建

这样一个完成的设计图就会在页面显示出来了

3.菜单功能,新建,打开,保存菜单
触发菜单事件需要继承自ICommand,而实现接口方法需要有一个类继承自这个接口,所以需要定义一个Reply类继承自接口ICommand,
3.1创建 ReplayCommand : ICommand
这个类必须实现CanExecute,Execute方法和CanExecuteChanged事件
其中Execute传入参数是点击菜单时触发事件的函数。
3.2新建菜单
新建ICommand类型属性NewCommand,这样页面绑定这个属性的时候就会触发里面的事件
在Page_Load事件里调用 this.NewCommand = new ReplayCommand(ExecuteNew, null);
这样新建功能就可以实现了

3.3打开菜单
新建ICommand类型属性OpenCommand,
在Page_Load事件里调用   this.OpenCommand = new ReplayCommand(this.ExecuteOpen, null);
实现ExeuteOpen方法
   private void ExecuteOpen(object obj)
        {
            var openFileDialog = new OpenFileDialog();
            if (openFileDialog.ShowDialog(Application.Current.MainWindow).Value)
            {
                this.LoadWorkflow(openFileDialog.FileName);
            }
        }
3.3.1 首先打卡一个选择框选择文件,如果选择了文件把文件名传入LoadWorkflow函数
3.3.2 LoadWorkflow函数
   private void LoadWorkflow(string name)
        {
            this.WorkflowDesignerObj = new WorkflowDesigner();
            this.WorkflowDesignerObj.ModelChanged += this.WorkflowDesignerModelChanged;
            this.WorkflowDesignerObj.Load(name);
        }
初始化WorkflowDesingerObj实例,
设置当改变模式改变的时候更新XML输入框
根据路径加载设计图

3.4保存功能,
新建一个ICommand类型的属性,SaveCommand
在Page_Load里加入 this.SaveCommand = new ReplayCommand(this.ExecuteSave, null);
在下面加入ExecuteSave方法
 private void ExecuteSave(object obj)
        {
            var saveFileDialog = new SaveFileDialog
            {
                AddExtension = true,
                DefaultExt = "xaml",
     
                Filter = "xaml files (*.xaml) | *.xaml;*.xamlx| All Files | *.*"
            };

            if (saveFileDialog.ShowDialog().Value)
            {
 
                this.workflowDesigner.Save(saveFileDialog.FileName);
            }
        }
这样保存功能就实现了。


4 实现客户自定义功能
自定义成功以后,可以把这个生成的xaml文件放到设定的目录里,
在调用位置,如果不是客户自定义而是开发阶段定义好的,那么声明workflowApplication可以用下面这句话
WorkflowApplication application = new WorkflowApplication(new AuthFlow(),input);
但是如果用了客户自定义功能,再实例化WorkflowApplication应该如下
 string fileName = @"D:\Test\WorkflowTest\Workflow.Web\bin\test.xaml";
  WorkflowApplication appliacation = new WorkflowApplication(ActivityXamlServices.Load(fileName));
当然这个路径需要外面传进来。
这个一个完整的客户自定义工作流流程就完成了。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值