使用silverlight构建一个工作流设计器(十三)(动态生成流程图片下载_上)

作者:互联网   出处:控件中国网   2014-11-05 19:18:23   阅读:1

9.1问题描述

今天有网友问,这个工作流设计器能不能生成对应的图片呢?我想不出生成图片能有什么作用,如果想用图片,我们大可以使用拷屏的方法保存到画图中,然后再保存在系统文件夹。不过作为一种尝试,不妨去试着去实现这个功能。

9.2遇到的困难

动态生成图片,首先想到的就是使用System.Drawring相关的类,但在silverlight中并没有提供对System.Drawring的支持,网上查了一下,得到的答案是微软并没有打算在silverlight中提供对System.Drawring的支持。

另外,在silverlight中无法直接进行文件的保存操作。

这些困难都说明,要想在silverlight中直接生成图片并保存,目前是不可行的。

9.3解决方法

       虽然我们不能直接在silverlight中生成图片保存,但我们的目的的生成图片,至于在什么地方生成图片,并没有固定的要求。我们知道,在asp.net中,我们经常使用System.Drawring相关类在动态生成图片,这个方法提醒我们,可以将生成图片的方法延迟到后台的服务中,然后访问后台生成的图片即可。用下面的图片来表示整个流程。

 

上面是一个理想的执行过程,但是在实际应用中发现有疑点问题,就是在生成图片后回调silverlight的函数中无法打开一个新的网页。只能把打开网页的代码放在按钮点击事件中,不过这对用户来说没有任何影响,只不过我们需要多做一点工作而已。在下面的代码中体现了这一点不同。

9.3.1 建立webservices文件

建立一个webservice文件,命名为createPic.asmx,在后台代码中根据传入的流程图xml描述文件动态生成图片。对应的框架代码如下:

  


using System;
using System.Collections.Generic; 
using System.Web;
using System.Web.Services;
using System.IO;
using System.Reflection;

using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;


namespace ShareDesigner.Web
{
    
/// <summary>
    
/// Summary description for CreatePic
    
/// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo 
= WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(
false)]
    
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    
// [System.Web.Script.Services.ScriptService]
    public class CreatePic : System.Web.Services.WebService
    {

        
public class RulePicture
        {
            
public void DrawingPic(Graphics gr) { }
        }
        
public class ActivityPicture
        {
            
public void DrawingPic(Graphics gr) { }
        }
        
public class ContainerPicture
        {
            
public void ParseWorkFlowXML(string xmlString)
            {
            }
            
int _width = 400;
            
public int Width { get { return _width; } }
            
int _height = 200;
            
public int Height { get { return _height; } }
            List
<RulePicture> _rulePictureCollection;
            
public List<RulePicture> RulePictureCollection
            {
                
get
                {
                    
if (_rulePictureCollection == null)
                        _rulePictureCollection 
= new List<RulePicture>();
                    
return _rulePictureCollection;
                }
            }
            List
<ActivityPicture> _activityPictureCollection;
            
public List<ActivityPicture> ActivityPictureCollection
            {
                
get
                {
                    
if (_activityPictureCollection == null)
                        _activityPictureCollection 
= new List<ActivityPicture>();
                    
return _activityPictureCollection;
                }
            }
        }

        [WebMethod] 
        
public void CreatePicture(string pictureName,string xml)
        {

            ContainerPicture con 
= new ContainerPicture();
            con.ParseWorkFlowXML(xml);

            Bitmap pg 
= new Bitmap(con.Width, con.Height);
             
            
            Graphics gr 
= Graphics.FromImage(pg);
            

            
for (int i = 0; i < con.RulePictureCollection.Count; i++)
            {
                con.RulePictureCollection[i].DrawingPic(gr);
            }
            
for (int i = 0; i < con.ActivityPictureCollection.Count; i++)
            {
                con.ActivityPictureCollection[i].DrawingPic(gr);
            }

             

            Font fn 
= new Font("@宋体"12);
            SolidBrush solidBlack 
= new SolidBrush(Color.Red);
            gr.DrawString(pictureName, fn, solidBlack, (
int)(pg.Width * 0.1), (int)(pg.Height * 0.1)); 


            MemoryStream stream 
= new MemoryStream();
            pg.Save(Server.MapPath(
"~/picture/" + pictureName+".png"), System.Drawing.Imaging.ImageFormat.Png); 
             

        }
    }
}

 

9.3.2 添加webservice引用

在流程容器页面Container.xaml添加一个按钮,在按钮事件中编写访问生成图片的代码,同时开发一个页面浏览生成的图片,代码如下所示,请注意其中的注释内容,另外,如果我们将项目部署到服务器上给客户用,那么需要修改动态设定服务路径,在下面的代码中有所体现。

 


string picName = "";
        
//连接创建图片服务,打开新的窗口访问图片
        private void btnCreatePicture_Click(object sender, RoutedEventArgs e)
        {
            picName 
= Guid.NewGuid().ToString(); 

            System.ServiceModel.BasicHttpBinding bind 
= new System.ServiceModel.BasicHttpBinding();
            System.ServiceModel.EndpointAddress endpoint 
= new System.ServiceModel.EndpointAddress(
                
new Uri(System.Windows.Browser.HtmlPage.Document.DocumentUri, "createpic.asmx"), null); 
            CreatePicture.CreatePicSoapClient client 
= new Shareidea.Web.UI.Control.Workflow.Designer.CreatePicture.CreatePicSoapClient(bind, endpoint); 

            client.CreatePictureCompleted 
+= new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_CreatePictureCompleted);
            client.CreatePictureAsync(picName, ToXmlString());

            Uri url 
= new Uri(System.Windows.Browser.HtmlPage.Document.DocumentUri, "picture.aspx?name=" + picName);
            System.Windows.Browser.HtmlPage.PopupWindow(url, 
"_blank"null); 
          
        }

        
void client_CreatePictureCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            
//下面这段代码无法弹出新的窗口,只能上面的方法中才能执行
            
           
// Uri url = new Uri(System.Windows.Browser.HtmlPage.Document.DocumentUri, "picture.aspx?name=" + picName);
           
// System.Windows.Browser.HtmlPage.PopupWindow(url, "_blank", null);

        }

 

9.3.3 建立图片显示页面

建立一个picture.aspx。这个文件接受一个参数pictureName,接受上一部的文件名称。根据参数检查是否存在这样的文件,如果存在,则将内容发送到客户端,如果不存在,那么显示一个错误消息,代入如下所示:

  


protected void Page_Load(object sender, EventArgs e)
        {
            
string fileName = "";
            
if (Page.Request.QueryString["name"!= null)
                fileName 
= Page.Request.QueryString["name"].ToString();

            
string filePath=Server.MapPath("~/picture/"+fileName+".png");
            FileInfo info 
= null;
            
long size = 0;
            info 
= new FileInfo(filePath);
            
int seconds = 0;
            
while (!info.Exists && seconds <5)
            { 
                info 
= new FileInfo(filePath); 
                System.Threading.Thread.Sleep(
1000);
                seconds
++;
            }
            
if (info.Exists)
            {
                size 
= info.Length;

                Response.ClearContent();
                Response.ContentType 
= "image/png"
                Response.WriteFile(filePath, 
0, size); 
                Response.End();   
            }
            Response.Write(
"您请求的图片不存在!"); 
           
        }

 

 到现在为止,一个动态生成流程图图片的框架就完成了,因为还没有编写具体的活动和规则的图片生成方法,所以只是生成一个显示文件名称的图片。下一章将具体完成生成图片的代码。

Copyright© 2006-2015 ComponentCN.com all rights reserved.重庆磐岩科技有限公司(控件中国网) 版权所有 渝ICP备12000264号 法律顾问:元炳律师事务所
客服软件
live chat