WF4小试牛刀之生成流程图

为何需要流程图?

用户可以清晰的看到流程参与对象、流程节点状态及其整个流程结构;

因为WF4设计器本身没有天然提供这一功能,所以还需自己动手DIY;生成窗体图片因为需要用到底层GUI功能,所以是单独建立一个WPF工程,然后通过暴露服务的方式,实现同步调用,并返回数据;

功能实现及其步骤:

1.加载流程

代码

        
/// <summary>
        
/// 加载流程设计器
        
/// </summary>
        
/// <param name="instance"></param>
        private void LoadWorkflowDesigner(System.Activities.Activity instance)
        {
            (
new DesignerMetadata()).Register();
            _workflowDesigner 
= new WorkflowDesigner();
            
if (instance is System.Activities.DynamicActivity)
            {
                instance 
= System.Activities.WorkflowInspectionServices.GetActivities(instance).First();
            }
            _workflowDesigner.Load(instance);

            
this.rehostGrid.Children.Clear();
            
this.rehostGrid.Children.Add(_workflowDesigner.View);

            _workflowDesigner.View.LayoutUpdated 
+= new EventHandler(View_LayoutUpdated);
        }

2.利用控件截图功能,实现对设计器控件截图;


        
/// <summary>
        
/// 创建屏幕截图
        
/// </summary>
        
/// <returns></returns>
        BitmapFrame CreateScreenShot()
        {
            
const double DPI = 96.0;
            
// 获取设计器下的主窗体设计器,this._workflowDesigner.View是指整个容器,容器包含的第一个子窗体才是主窗体设计器
            DesignerView designerView = (DesignerView)VisualTreeHelper.GetChild(this._workflowDesigner.View, 0);
            Visual visual 
= designerView.RootDesigner;
            Rect size 
= VisualTreeHelper.GetDescendantBounds(visual);
            
int imageWidth = (int)size.Width;  
            
int imageHeight = (int)size.Height;
            RenderTargetBitmap renderBitmap 
= new RenderTargetBitmap(imageWidth, imageHeight, DPI, DPI, PixelFormats.Pbgra32);
            renderBitmap.Render(visual);
            
return BitmapFrame.Create(renderBitmap);
        }

        
/// <summary>

3.两种生成图的方式;a.生成图然后返回图片路径 b.直接返回生成后的二进制数据


        
/// <summary>
        
/// 获取二进制图片数据
        
/// </summary>
        
/// <returns></returns>
        public byte[] GetPictureBytes()
        { 
            Dispatcher.Invoke((Action)(() 
=>
            {
                
try
                {
                    MemoryStream ms 
= new MemoryStream();
                    JpegBitmapEncoder encoder 
= new JpegBitmapEncoder();
                    encoder.Frames.Add(BitmapFrame.Create(
this.CreateScreenShot()));
                    encoder.Save(ms);
                    ms.Close();
                    ImageBytes 
= ms.ToArray();
                }
catch(Exception ex)
                { MessageBox.Show(ex.Message); }
                
// 关闭窗口
                this.Close();
                
// 优先级必须为System.Windows.Threading.DispatcherPriority.Background,否则流程图会生成不全;
            }), System.Windows.Threading.DispatcherPriority.Background);
            
return ImageBytes;
        }

        
/// <summary>
        
/// 创建本地图片
        
/// </summary>
        
/// <param name="fileName">生成图片文件名称</param>
        
/// <returns>是否生成成功</returns>
        public bool CreateLocalPircture(string fileName)
        {
            
bool b = false;

            Dispatcher.Invoke((Action)(() 
=>
            {
                
try
                {
                    
string fileDirectory = fileName.Substring(0, (fileName.LastIndexOf('\\'+ 1));

                    
// 如果目录不存在,则创建
                    if (!Directory.Exists(fileDirectory))
                    {
                        Directory.CreateDirectory(fileDirectory);
                    }

                    
using (FileStream fs = new FileStream(fileName, FileMode.Create))
                    {
                        BitmapEncoder encoder 
= new JpegBitmapEncoder();
                        encoder.Frames.Add(BitmapFrame.Create(
this.CreateScreenShot()));
                        encoder.Save(fs);
                        fs.Close();
                    }
                    b 
= true;
                }
                
catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
                
// 关闭窗口
                this.Close();

                
// 优先级必须为System.Windows.Threading.DispatcherPriority.Background,否则流程图会生成不全;
                }), System.Windows.Threading.DispatcherPriority.Background);
            
return b;
        }

3.WCF调用生成流程窗体


    [ServiceContract]
    
public interface IWFPictureFactory
    {
        
/// <summary>
        
/// 根据申请ID获取二进制图片数据
        
/// </summary>
        
/// <param name="aiid">申请ID</param>
        
/// <returns></returns>
        [OperationContract]
        
byte[] GetPictureBytes(int aiid);

        
/// <summary>
        
/// 根据申请ID和图片文件名称生成本地图片
        
/// </summary>
        
/// <param name="aiid">申请ID</param>
        
/// <param name="filename">文件名称</param>
        
/// <returns></returns>
        [OperationContract]
        
bool CreateLocalPircture(int aiid, string filename);
    }

    
public class WFPictureFactory : IWFPictureFactory
    {
        
/// <summary>
        
/// 根据申请ID获取二进制图片数据
        
/// </summary>
        
/// <param name="aiid">申请ID</param>
        
/// <returns></returns>
        public byte[] GetPictureBytes(int aiid)
        {
            MainWindow window 
= new MainWindow();
            window.AIID 
= aiid;
            window.Show();
            var bytes
= window.GetPictureBytes();
            
return bytes;
        }

        
/// <summary>
        
/// 根据申请ID和图片文件名称生成本地图片
        
/// </summary>
        
/// <param name="aiid">申请ID</param>
        
/// <param name="filename">文件名称</param>
        
/// <returns></returns>
        public bool CreateLocalPircture(int aiid,string filename)
        {
            MainWindow window 
= new MainWindow();
            window.AIID 
= aiid;
            window.Show();
            var b 
= window.CreateLocalPircture(filename);
            
return b;
        }

 4.启动/关闭服务

代码

        ServiceHost myServiceHost 
= null;
        
void StartService(Type type)
        {
            
try
            {
                
//Instantiate new ServiceHost with the singleton instance being passed in
                myServiceHost = new ServiceHost(type);
                myServiceHost.Open();
                lblMsg.Content 
= "服务已启动!";

            }
            
catch(Exception ex) {
                lblMsg.Content 
= "启动失败!";
                System.Windows.MessageBox.Show(ex.Message);
            }
        }

        
void StopService()
        { 
            
if(myServiceHost!=null){
                
try
                {
                    myServiceHost.Close();
                    lblMsg.Content 
= "服务已关闭!";

                }
                
catch (Exception ex)
                {
                    lblMsg.Content 
= "关闭服务失败!";
                    System.Windows.MessageBox.Show(ex.Message);
                }
            }
        }

 未完待续ing!下一步攻克流程节点状态显示的问题! 

Demo下载:https://files.cnblogs.com/yizhuqing/AWFP.WFPictureBuilder.zip 

作者:柱子
         
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/yizhuqing/p/1801345.html