none
自定义工作流设计器(2) RRS feed

  • 常规讨论

  • 3如何在wf中添加Activities(能在workflow中添加或删除Activitie,并能修改activity的属性)
    1.在WorkflowDesignerControl.cs中添加自定义的工具箱
     
    public WorkflowDesignerControl()
            
    {
                InitializeComponent();

                Toolbox toolbox 
    = new Toolbox(this);
                
    this.propertyGridSplitter.Panel1.Controls.Add(toolbox);
                toolbox.Dock 
    = DockStyle.Fill;
                toolbox.BackColor 
    = BackColor;
                toolbox.Font 
    = WorkflowTheme.CurrentTheme.AmbientTheme.Font; 

                WorkflowTheme.CurrentTheme.ReadOnly 
    = false;
                WorkflowTheme.CurrentTheme.AmbientTheme.ShowConfigErrors 
    = false;
                WorkflowTheme.CurrentTheme.ReadOnly 
    = true;

                
    this.propertyGrid.BackColor = BackColor;
                
    this.propertyGrid.Font = WorkflowTheme.CurrentTheme.AmbientTheme.Font;

                AppDomain.CurrentDomain.AssemblyResolve 
    += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
            }


    2.使WorkflowDesignerControl中的工具箱运行时加载Activitie(可以是自定义的)
     在ToolBoxItems.txt中注册
     例如我有个自定义的basic Activitie,如果要把这个Activiti加入工具箱中可以在ToolBoxItems.txt中这样写
       ActivityLibrary.MessageActivity, ActivityLibrary
     运行后就可以看到工具箱中有MessageActivity
    3.在设计器中选择Activity并编辑属性
     在WorkflowDesignerControl.cs中注册事件SelectionChanged
     

    ISelectionService selectionService = GetService(typeof(ISelectionService)) as ISelectionService;

                        
    if (selectionService != null)
                        
    {
                            selectionService.SelectionChanged 
    += new EventHandler(OnSelectionChanged);
                        }


      实现OnSelectionChanged事件
     

     private void OnSelectionChanged(object sender, EventArgs e)
            
    {
                ISelectionService selectionService 
    = GetService(typeof(ISelectionService)) as ISelectionService;

                
    if (selectionService != null)
                
    {
                    
    this.propertyGrid.SelectedObjects = new ArrayList(selectionService.GetSelectedComponents()).ToArray();
                }

            }


     这样,当WorkflowDesignerControl运行时,在右边下角会显示会选择所选择Activity的属性
    4.使工作流设计器支持删除功能
    在WorkflowDesignerControl.cs中加入方法DeleteSelected,支持在设计器中删除Activity.

    public void DeleteSelected()
            
    {
                ISelectionService selectionService 
    = (ISelectionService)this.GetService(typeof(ISelectionService));

                
    if (selectionService != null)
                
    {
                    
    if (selectionService.PrimarySelection is Activity)
                    
    {
                        Activity activity 
    = (Activity)selectionService.PrimarySelection;

                        
    if (activity.Name != this.WorkflowName)
                        
    {
                            activity.Parent.Activities.Remove(activity);
                            
    this.workflowView.Update();
                        }

                    }

                }

            }
     

           
    在界面工具条上添加Button,属性如下
      Name: btnDelete
     DisplayStyle: Text
     Text: “Remove Activity”
    在click事件中写入对WorkflowDesignerControl中DeleteSelected方法的调用

    private void btnDelete_Click(object sender, EventArgs e)
            
    {
                
    this.workflowDesignerControl.DeleteSelected();
            }

    5.使工作流设计器实现保存,编译,运行和打开已保存工作流的功能。
    在工具条上再次添加按钮名称分别为打开,保存,编译和运行,在这些按钮的事件触发程序中调用workflowDesignerControl中已经定义好的方法
    5.1在workflowDesignerControl中添加方法,加载已经存在的工作流模板文件
      

     public void LoadExistingWorkflow()
            
    {
                OpenFileDialog openFileDialog 
    = new OpenFileDialog();
                openFileDialog.Filter 
    = "xoml files (*.xoml)|*.xoml|All files (*.*)|*.*";
                openFileDialog.FilterIndex 
    = 1;
                openFileDialog.RestoreDirectory 
    = true;

                
    if (openFileDialog.ShowDialog() == DialogResult.OK)
                
    {
                    
    using (XmlReader xmlReader = XmlReader.Create(openFileDialog.FileName))
                    
    {
                        WorkflowMarkupSerializer serializer 
    = new WorkflowMarkupSerializer();
                        
    this.workflow = (SequentialWorkflowActivity)serializer.Deserialize(xmlReader);
                        
    this.LoadWorkflow();

                        
    this.XomlFile = openFileDialog.FileName;
                        
    this.Text = "Designer Hosting Sample -- [" + openFileDialog.FileName + "]";
                    }

                }

            }


    5.2:保存功能实现
     

    private void SaveFile()
            
    {
                
    if (this.XomlFile.Length != 0)
                
    {
                    
    this.SaveExistingWorkflow(this.XomlFile);
                }

                
    else
                
    {
                    SaveFileDialog saveFileDialog 
    = new SaveFileDialog();
                    saveFileDialog.Filter 
    = "xoml files (*.xoml)|*.xoml|All files (*.*)|*.*";
                    saveFileDialog.FilterIndex 
    = 1;
                    saveFileDialog.RestoreDirectory 
    = true;

                    
    if (saveFileDialog.ShowDialog() == DialogResult.OK)
                    
    {
                        
    this.SaveExistingWorkflow(saveFileDialog.FileName);
                        
    this.Text = "Designer Hosting Sample -- [" + saveFileDialog.FileName + "]";
                    }

                }

            }


    5.3:编译功能实现
     

    public bool Compile()
            
    {
                
    return this.Compile(true);
            }


     
    public bool Compile(bool showMessage)
     
    {
         
    if (!this.Save(false))
         
    {
             
    return false;
         }


         
    if (!File.Exists(this.XomlFile))
         
    {
             MessageBox.Show(
    this"Cannot locate xoml file: " + Path.Combine(Path.GetDirectoryName(this.GetType().Assembly.Location), XomlFile), this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
             
    return false;
         }


         
    bool compileOK = true;

         Cursor cursor 
    = this.Cursor;
         
    this.Cursor = Cursors.WaitCursor;

         
    try
         
    {
             
    // Compile the workflow
             String[] assemblyNames = { AdditionalAssembies };
             WorkflowCompiler compiler 
    = new WorkflowCompiler();
             WorkflowCompilerParameters parameters 
    = new WorkflowCompilerParameters(assemblyNames);
             parameters.LibraryPaths.Add(Path.GetDirectoryName(
    typeof(ActivityLibrary.MessageActivity).Assembly.Location));
             parameters.GenerateInMemory 
    = true;
             WorkflowCompilerResults compilerResults 
    = compiler.Compile(parameters, this.XomlFile);

             inMemoryAssembly 
    = compilerResults.CompiledAssembly;

             StringBuilder errors 
    = new StringBuilder();

             
    foreach (CompilerError compilerError in compilerResults.Errors)
             
    {
                 errors.Append(compilerError.ToString() 
    + '\n');
             }


             
    if (errors.Length != 0)
             
    {
                 MessageBox.Show(
    this, errors.ToString(), this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
                 compileOK 
    = false;
             }

             
    else if (showMessage)
             
    {
                 MessageBox.Show(
    this"Workflow compiled successfully. Compiled assembly:\n" + compilerResults.CompiledAssembly.GetName(), this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
             }

         }

         
    finally
         
    {
             
    this.Cursor = cursor;
         }


         
    return compileOK;
     }


    注意:
    parameters.GenerateInMemory = true;这时assembly只在内存中生成,不输出到文件
    如果要生成.dll文件,需要修改为
    parameters.GenerateInMemory = false;
    parameters.OutputAssembly = string.Format("{0}.dll", this.WorkflowName);
     
    6:在工具条的事件中调用这些方法
    测试一下
    如果还没有保存,运行后会先保存并编译。

    补传 本文所示代码:demo

    转自:http://www.cnblogs.com/lodestar/

    2009年6月25日 7:49