開源項目Silverlight工作流設(shè)計器_第1頁
開源項目Silverlight工作流設(shè)計器_第2頁
開源項目Silverlight工作流設(shè)計器_第3頁
開源項目Silverlight工作流設(shè)計器_第4頁
開源項目Silverlight工作流設(shè)計器_第5頁
已閱讀5頁,還剩131頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

【開源項目】Silverlight工作流設(shè)計器Silverlight工作流設(shè)計器是一款開源項目,支持用戶在線設(shè)計工作流程,或者項目流程,支持在線拖拽,以及鼠標(biāo)右鍵支持。具體來說,這樣的流程設(shè)計器應(yīng)該具有以下的特點:圖形化的方式顯示流程支持拖拽創(chuàng)建和修改流程導(dǎo)出圖形對應(yīng)的xml描述文件根據(jù)流程xml描述文件

Silverlight工作流設(shè)計器是一款開源項目,支持用戶在線設(shè)計工作流程,或者項目流程,支持在線拖拽,以及鼠標(biāo)右鍵支持。具體來說,這樣的流程設(shè)計器應(yīng)該具有以下的特點:

圖形化的方式顯示流程

支持拖拽創(chuàng)建和修改流程

導(dǎo)出圖形對應(yīng)的xml描述文件

根據(jù)流程xml描述文件顯示流程圖點擊訪問本系列專題文章源代碼下載數(shù)據(jù)庫下載Silverlight構(gòu)建圖形化工作流程設(shè)計器(一)前言Silverlight發(fā)布已經(jīng)很久了,具體是什么就不多說,大家一定很清楚。最關(guān)心的就是其中的跨瀏覽器能力,以及強大的用戶界面表現(xiàn)能力。于是決定使用它來實現(xiàn)一個流程設(shè)計工具,以替代以前的流程設(shè)計器(原來是用vml實現(xiàn),只能在IE瀏覽器上工作),因為第一次接觸silverlight,在學(xué)習(xí)、工作的過程中肯定會遇到很多的問題前言Silverlight發(fā)布已經(jīng)很久了,具體是什么就不多說,大家一定很清楚。最關(guān)心的就是其中的跨瀏覽器能力,以及強大的用戶界面表現(xiàn)能力。于是決定使用它來實現(xiàn)一個流程設(shè)計工具,以替代以前的流程設(shè)計器(原來是用vml實現(xiàn),只能在IE瀏覽器上工作),因為第一次接觸silverlight,在學(xué)習(xí)、工作的過程中肯定會遇到很多的問題,將這個學(xué)習(xí)新知識、解決問題的過程記錄下來,肯定能找到許多志同道合的朋友,也請大家抱著這種態(tài)度閱讀本文。本文主要講述使用2008開發(fā)一個基于silverlight的流程設(shè)計器。在進(jìn)入正文之前,先說一下開發(fā)環(huán)境的配置。使用2008作為開發(fā)工具,需要下載一個Silverlighttoolsforvirsualstudio2008sp1,地址在/GetStarted/,安裝后就可以使用2008來開發(fā)silverlight應(yīng)用了。本系列文章包含以下幾部分(可能有變)。系統(tǒng)范圍系統(tǒng)設(shè)計類設(shè)計Xml設(shè)計美化重構(gòu)一、系統(tǒng)范圍在開始之前,先來看一下系統(tǒng)將要完成什么樣的功能。具體來說,這樣的流程設(shè)計器應(yīng)該具有以下的特點:圖形化的方式顯示流程支持拖拽創(chuàng)建和修改流程導(dǎo)出圖形對應(yīng)的xml描述文件根據(jù)流程xml描述文件顯示流程圖注意:本文只將焦點放置在圖形的描述上,不涉及流程的各種屬性,不過您完全可以在此基礎(chǔ)上創(chuàng)建一個包含流程屬性設(shè)置的應(yīng)用程序。另外,本文是隨著程序的編寫進(jìn)度而撰寫的,程序在不斷的完善,本文也將不斷的修改完善。在這個過程中將隨時提供可以運行的程序供下載。下面的圖形具體的顯示了系統(tǒng)將要完成的功能:二、系統(tǒng)設(shè)計從上面的圖形來看,我們的系統(tǒng)將包含三個大的對象:活動(activity):如上圖中的方框圖(三角圖,圓形圖)對應(yīng)的對象,這個對象代表工作流中的一個活動。規(guī)則(rule):如上圖中的帶箭頭的直線,二、系統(tǒng)設(shè)計從上面的圖形來看,我們的系統(tǒng)將包含三個大的對象:活動(activity):如上圖中的方框圖(三角圖,圓形圖)對應(yīng)的對象,這個對象代表工作流中的一個活動。規(guī)則(rule):如上圖中的帶箭頭的直線,這個對象代表了工作流中的規(guī)則。設(shè)計面板:設(shè)計面板是流程圖的容器對象。系統(tǒng)對象確定以后,再來看一下系統(tǒng)功能描述:新增活動:創(chuàng)建一個活動的實例,并將這個實例添加到設(shè)計面板中。新增規(guī)則:創(chuàng)建一個規(guī)則的實例,并將這個實例添加到設(shè)計面板中。拖拽規(guī)則實例:規(guī)則實例可以被鼠標(biāo)拖拽,規(guī)則實例表現(xiàn)為一個帶箭頭的直線,可以拖拽直線的開頭部分,也可以拖拽直線的結(jié)尾部分,或者拖拽直線中間的部分。拖拽開頭部分時,直線的開頭部分隨鼠標(biāo)變化位置,但結(jié)尾部分位置不改變。拖拽結(jié)尾部分時,直線的開頭部分隨鼠標(biāo)變化位置,但結(jié)束部分位置不改變。拖拽中間部分,整條直線隨鼠標(biāo)改變位置。在拖拽開頭或者結(jié)尾部分,并在某一個活動實例上放開鼠標(biāo)左鍵,那么將建立活動和規(guī)則的關(guān)聯(lián)關(guān)系。拖拽活動實例:活動實例可以被鼠標(biāo)拖拽,如果這個活動有相關(guān)聯(lián)的規(guī)則,那么規(guī)則位置也隨鼠標(biāo)變化。支持活動和規(guī)則的刪除:支持刪除活動實例和規(guī)則實例,刪除活動實例時,同時刪除關(guān)聯(lián)的規(guī)則實例。根據(jù)圖形導(dǎo)出xml文件:導(dǎo)入xml文件生成圖形:通過上面的分析,對流程設(shè)計器有一個大概的了解,在進(jìn)入具體的類設(shè)計之前還是有幾點需要提醒的:silverlight和的運行模型的不同和編制程序時的注意點。Silverlight和都可以使用c#進(jìn)行編程設(shè)計,但他們的運行方式卻截然不同。A中的c#代碼是需要您的web服務(wù)器執(zhí)行的(IIS)后,將執(zhí)行后的html代碼發(fā)送到客戶端的瀏覽器,而silverlight中的c#代碼卻是在客戶端的瀏覽器中運行的。對于頁面,您的每一次請求都將實例化一個Page類的對象,你在服務(wù)器代碼中的C#代碼的各種變量都將被重新初始化。但是silverlight不需要發(fā)送代碼到服務(wù)器,而是在本地瀏覽器中完成了您編寫的C#代碼,這種方式更類似于傳統(tǒng)的VB或者VC編寫的c/s架構(gòu)的程序。正是基于以上的理解,我們把silverlight看作是c/s架構(gòu)的編程方式,所以可以進(jìn)行上面的各種類的設(shè)計。這樣使用c/s編程方式編寫一個流程設(shè)計器,通過silverlight技術(shù),最終可以通過瀏覽器來給客戶使用。對客戶而言,這是一個b/s架構(gòu)的程序,而對于程序員來說,其實是c/s架構(gòu)的。下面將進(jìn)入具體的類的設(shè)計,并提供一個可運行的程序。Silverlight構(gòu)建圖形化工作流程設(shè)計器(二)三、類的設(shè)計在進(jìn)行類設(shè)計之前,先說一下silverlight中使用怎么表示上面描述的類。在silverlight可以使用用戶控件(silverlightusercontro)來描述各種具有用戶界面的類,如上文所講的活動類,規(guī)則類。操作很簡單,在2008中增加一個新的silverlightuserc三、類的設(shè)計在進(jìn)行類設(shè)計之前,先說一下silverlight中使用怎么表示上面描述的類。在silverlight可以使用用戶控件(silverlightusercontro)來描述各種具有用戶界面的類,如上文所講的活動類,規(guī)則類。操作很簡單,在2008中增加一個新的silverlightusercontro就可以了。其實是一個xaml文件。在xaml文件中布局用戶界面,在對應(yīng)的xam.cs文件中編寫后臺方法即可。需要說一下的是,在進(jìn)行鼠標(biāo)拖動活動或者規(guī)則移動時,規(guī)則和活動的動態(tài)定位使用的是相對于容器來的相對位置,也就是使用Canvas.Top和Canvas.Left屬性進(jìn)行定位。還有一點需要說明的就是,對于活動和規(guī)則的關(guān)聯(lián)有幾點需要注意。一個規(guī)則可以關(guān)聯(lián)到兩個不同的活動,一個為起始活動(起始端點關(guān)聯(lián))。一個為終結(jié)活動(終結(jié)端點關(guān)聯(lián))規(guī)則的起始活動和終結(jié)活動不能為同一個活動。任何兩個規(guī)則,他們的起始活動和終結(jié)活動不能相同,也就是說在不同的兩個活動之間,不能有重復(fù)的規(guī)則關(guān)聯(lián)。3.1活動類的設(shè)計(Activity)活動代表工作流中的一個活動節(jié)點,在流程圖上表現(xiàn)為一個方框圖,可以被拖拽,可以關(guān)聯(lián)到一個規(guī)則的開始或者結(jié)束。3.1.1Xam下面的代碼表示了活動類的外觀<UserControx:Class="Shareidea.Web.UI.Contro.Workflow.Designer.Activity"

xmlns=/winfx/2006/xam/presentation

xmlns:x=/winfx/2006/xam

MouseLeftButtonDown="UserContro_MouseLeftButtonDown"

MouseLeftButtonUp="UserContro_MouseLeftButtonUp"

MouseMove="UserContro_MouseMove"

MouseEnter="UserContro_MouseEnter"

MouseLeave="UserContro_MouseLeave"

Width="100"Height="60">

<CanvasName="container">

<RectangleHorizontalAlignment="Stretch"VerticalAlignment="Stretch"Fil="Green"/>

<BorderCornerRadius="10"Background="Green"Opacity="0.9"Width="100"Height="60">

<TextBoxName="Title"Text="新建活動"BorderBrush="Green"FontSize="12"Background="Green"

Height="30"Width="60"MouseEnter="TextBox_MouseEnter"></TextBox>

</Border>

<HyperlinkButtonCanvas.ZIndex="10000"Padding="10555"MouseLeave="HyperlinkButton_MouseLeave"Foreground="Red"Width="65"Height="25"Canvas.Top="50"Canvas.Left="100"Background="Yellow"Name="btnDelete"Click="HyperlinkButton_Click"ClickMode="Release"Content="刪除活動"></HyperlinkButton>

</Canvas>

</UserContro>從上面代碼可以看出,活動類主要包含一個矩形的圖形,還有一個刪除按鈕。圖形顯示如下:

3.12后臺代碼活動類主要實現(xiàn)主要動作(函數(shù))鼠標(biāo)拖拽刪除關(guān)聯(lián)到規(guī)則(增加,刪除)輸出活動xml描述導(dǎo)入xml描述還有一些主要屬性:活動標(biāo)示(ID)活動名稱(Name)所有關(guān)聯(lián)的規(guī)則的集合以及一些主要的事件:移動刪除具體代碼不再貼出,大家可以下載源代碼運行。

一個規(guī)則從圖形上被分成三個部分,起始端點(白色),中間線段,終結(jié)端點(黑色)(在實際環(huán)境中,應(yīng)該整體表現(xiàn)為一個帶箭頭的線段,為了便于描述,先這樣表示,在后面的美化部分將作修改)。這三個部分都可以被鼠標(biāo)拖動,當(dāng)拖動起始端點時,起始端點隨著鼠標(biāo)變化而變化位置,終結(jié)端點不動,中間線段根據(jù)起始端點和終結(jié)端點計算位置。拖動終結(jié)端點類似于拖動起始端點。當(dāng)拖動中間線段時,整個規(guī)則圖形(包括起始端點,中間線段,終結(jié)端點)隨著鼠標(biāo)移動而移動。另外一個需要仔細(xì)考慮的是,當(dāng)拖動規(guī)則,并且將端點移動到活動上時,進(jìn)行規(guī)則和活動關(guān)聯(lián)的時機。有以下幾個時機可以考慮:拖動規(guī)則進(jìn)入活動范圍。(活動的MouseEnter事件)拖動規(guī)則結(jié)束后,放開鼠標(biāo)。對于第一種情況,當(dāng)拖動規(guī)則并且進(jìn)入互動范圍時,無法觸發(fā)活動的MouseEnter事件。暫時無法解決。(但是在放開鼠標(biāo),并且在活動上移動時,此時觸發(fā)MouseEnter事件。但是這樣做會存在某些特定的bug)。因此使用第二種方法進(jìn)行關(guān)聯(lián),也就是在規(guī)則的MouseLeftButtonUp事件中遍歷當(dāng)前所有的活動,檢查規(guī)則是否處于活動的范圍內(nèi),如果在,那么就進(jìn)行關(guān)聯(lián)。3.2.1xaml下面的代碼描述了規(guī)則類的xaml1<UserControx:Class="Shareidea.Web.UI.Contro.Workflow.Designer.Rule"

2xmlns="/winfx/2006/xam/presentation"

3xmlns:x="/winfx/2006/xam"

4MouseEnter="UserContro_MouseEnter"

5MouseLeave="UserContro_MouseLeave"

6>

7<CanvasCanvas.ZIndex="100">

8<EllipseName="begin"Canvas.Top="0"Canvas.Left="0"Canvas.ZIndex="100"

9Width="10"Height="10"Fil="White"

10Stroke="Black"StrokeThickness="0"

11MouseLeftButtonDown="Point_MouseLeftButtonDown"

12MouseLeftButtonUp="Point_MouseLeftButtonUp"

13MouseMove="Point_MouseMove"

14>

15</Ellipse>

16<LineName="line"Canvas.ZIndex="50"

17X1="5"Y1="5"X2="45"Y2="45"

18Stroke="#336699"StrokeThickness="5"

19MouseLeftButtonDown="Line_MouseLeftButtonDown"

20MouseLeftButtonUp="Line_MouseLeftButtonUp"

21MouseMove="Line_MouseMove"

22>

23</Line>

24<CanvasCanvas.Top="40"Canvas.Left="40"Name="end"Canvas.ZIndex="100"

25MouseLeftButtonDown="Point_MouseLeftButtonDown"

26MouseLeftButtonUp="Point_MouseLeftButtonUp"

27MouseMove="Point_MouseMove">

28

29<Ellipse

30Width="10"Height="10"Fil="Black"

31Stroke="Black"StrokeThickness="1">

32</Ellipse>

33</Canvas>

34<HyperlinkButtonCanvas.ZIndex="1000"MouseLeave="HyperlinkButton_MouseLeave"Foreground="Red"Padding="10555"Width="65"Height="25"Canvas.Left="50"Background="Yellow"Name="btnDelete"Click="HyperlinkButton_Click"ClickMode="Release"Content="刪除規(guī)則"></HyperlinkButton>

35</Canvas>

36</UserContro>

373.2.2后臺代碼規(guī)則類主要實現(xiàn)主要動作(函數(shù))鼠標(biāo)拖拽刪除關(guān)聯(lián)到活動(增加,刪除)輸出規(guī)則xml描述導(dǎo)入xml描述還有一些主要屬性:規(guī)則標(biāo)示(ID)規(guī)則名稱(Name)起始活動結(jié)束活動以及一些主要的事件:移動刪除3.3容器類的設(shè)計容器類主要功能就是用來提供一個設(shè)計面板,可以增加,刪除工作流元素(活動,規(guī)則),導(dǎo)入xml和導(dǎo)出xm。3.3.1xam下面的容器的xaml代碼1<UserControx:Class="design.Page"

2xmlns="/winfx/2006/xam/presentation"

3xmlns:x="/winfx/2006/xam">

4<Gridx:Name="LayoutRoot"Background="#A0A0A0"ShowGridLines="False">

5<Grid.RowDefinitions>

6<RowDefinitionHeight="35"/>

7<RowDefinitionHeight="*"/>

8</Grid.RowDefinitions>

9<Grid.ColumnDefinitions>

10<ColumnDefinitionWidth="150"/>

11<ColumnDefinitionWidth="*"/>

12</Grid.ColumnDefinitions>

13<CanvasGrid.ColumnSpan="2"Grid.Row="0"Width="1150"HorizontalAlignment="Left"Grid.Column="0"Background="#0054e3">

14<TextBlockMargin="10500"FontSize="16"Foreground="White"Text="流程設(shè)計器"></TextBlock>

15</Canvas>

16<StackPaneBackground="#e5eff8"Width="150"Height="600"Grid.Row="1"Grid.Column="0">

17<TextBlockText="流程名稱:"Padding="10"></TextBlock>

18<TextBoxName="WorkFlowName"Width="130"HorizontalAlignment="Left"Margin="100010"></TextBox>

19<ButtonVerticalAlignment="Top"Margin="55105"HorizontalAlignment="Right"Width="60"Height="30"Background="Red"Click="AddActivity_Click"Content="添加活動"/>

20<ButtonVerticalAlignment="Top"Margin="55105"HorizontalAlignment="Right"Width="60"Height="30"Background="Red"Click="AddRule_Click"Content="添加規(guī)則"/>

21

22</StackPane>

23<CanvasGrid.Row="1"Grid.Column="1"HorizontalAlignment="Left"Name="cnsDesignerContainer"Width="1000"Height="600"Background="#dcdcdc">

24</Canvas>

25<CanvasName="MessageBody">

26<RectangleHorizontalAlignment="Center"VerticalAlignment="Center"Fil="#FF8A8A8A"></Rectangle>

27<BorderCanvas.Top="200"Canvas.Left="300"CornerRadius="30"Background="#FF5C7590"Width="400"Height="200">

28<StackPaneVerticalAlignment="Center"Margin="20">

29<TextBlockName="MessageTitle"Text="消息內(nèi)容"FontSize="18"HorizontalAlignment="Center"Margin="10"></TextBlock>

30<ButtonContent="關(guān)閉"Width="100"Height="50"FontSize="18"Click="Button_Click"></Button>

31</StackPane>

32</Border>

33</Canvas>

34</Grid>

35</UserContro>

36下圖是容器的外觀

3.3.2后臺代碼規(guī)則類主要實現(xiàn)主要動作(函數(shù))增加活動刪除活動增加規(guī)則刪除規(guī)則導(dǎo)入xm導(dǎo)出xm還有一些主要屬性:活動集合規(guī)則集合流程標(biāo)示(ID)流程名稱(Name)好了,其實也沒有說什么,大家還是看代碼吧,因為比較倉促,有些寫得比較亂,有些也沒有注釋,以后會慢慢完善,既然是第一個版本,就叫做workflowDesigner.S0.1版吧。下面的章節(jié)進(jìn)入導(dǎo)出xml及根據(jù)xml文件生成流程圖,并且會討論一些更有意思的話題.源代碼下載Silverlight構(gòu)建圖形化工作流程設(shè)計器(三)新功能調(diào)查:系統(tǒng)到這里已經(jīng)具備一個設(shè)計器的雛形了,當(dāng)然還有很多需要完善的功能,如果您在這方面有經(jīng)驗,請?zhí)岢瞿膶氋F意見,也可以留下您想要實現(xiàn)的功能,在后續(xù)版本中,我們將考慮您的意見,非常感謝:)本文繼續(xù)前文的內(nèi)容,主要講述與導(dǎo)入xm,導(dǎo)出xm,xml存儲有新功能調(diào)查:系統(tǒng)到這里已經(jīng)具備一個設(shè)計器的雛形了,當(dāng)然還有很多需要完善的功能,如果您在這方面有經(jīng)驗,請?zhí)岢瞿膶氋F意見,也可以留下您想要實現(xiàn)的功能,在后續(xù)版本中,我們將考慮您的意見,非常感謝:)本文繼續(xù)前文的內(nèi)容,主要講述與導(dǎo)入xm,導(dǎo)出xm,xml存儲有關(guān)的一些內(nèi)容。包含以下部分:設(shè)計一個流程圖的xml描述文件將流程圖導(dǎo)出為xm根據(jù)xml文件呈現(xiàn)流程圖在完成以上內(nèi)容后,進(jìn)一步深入思考,既然可以將流程的當(dāng)前狀態(tài)保存為xm,那么在每次流程改變的時候?qū)?dāng)前狀態(tài)保存到內(nèi)存中,在需要的時候再從內(nèi)存中還原,就可以實現(xiàn)word里面的撤銷與前進(jìn)的功能了,所以功能就加多了兩個。撤銷前進(jìn)在進(jìn)一步,如果將內(nèi)存保存的xml對象集合按照一定的頻率自動播放,是不是就是一個動畫了,呵呵,我們可以用這個來做一個簡單的動畫片了。四、xml存取4.1xml內(nèi)容就是將流程圖保存為xml文件,以及根據(jù)xml文件還原流程圖的功能。首先來看一下xml文件的格式。Xml文件用來描述流程的,在本文中,流程的布局信息主要有幾個方面:流程的屬性信息。例如流程名稱等活動和規(guī)則的屬性信息,例如活動名稱等活動和規(guī)則的位置信息活動和規(guī)則的關(guān)聯(lián)信息我們設(shè)計出一個可以完全描述上面內(nèi)容的xml文件即可,下面給出這個xml描述的一個實現(xiàn)。<?xmversion="1.0"encoding="utf-8"standalone="yes"?>

<WorkFlowID=""Name=""Description="">

<Activitys>

<ActivityActivityID=""ActivityName=""PositionX=""PositionY=""ZIndex="">

</Activity>

</Activitys>

<Rules>

<RuleRuleID=""RuleName=""BeginActivityID=""EndActivityID=""BeginPointX=""BeginPointY=""EndPointX=""EndPointY=""ZIndex="">

</Rule>

</Rules>

</WorkFlow>上面的內(nèi)容不用多講了,大家看名字應(yīng)該可以猜的出來。我們還可以使用xsd.exe工具(.netframeworksdk里面帶有)生成對應(yīng)的workflow.xsd文件,在根據(jù).xsd文件生成Class,這個class就是操作這個xml文件的,.net真是太方便了。(這里就先不這么做了,而直接使用LINQToXml來操作上面的xml文件)如果您不了解xml相關(guān)的一些技術(shù),可以參考/xm/default.asp或者/(中文版)4.2導(dǎo)入、導(dǎo)出有幾個生成xml的方法。一個是將流程對象序列化,使用對象序列化的方法。另一個是讓對象自己生成xml片段,這里采用第二種方法。首先為了導(dǎo)入導(dǎo)出xm,容器、活動、規(guī)則、類需要增加兩個方法。ToXmlString()LoadFromXmlString(stringxmlNode)第一個用于生成表達(dá)本對象的xml片段,第二個用戶根據(jù)xml片段來生成相應(yīng)的對象。使用這兩個方法就可以將流程當(dāng)前狀態(tài)轉(zhuǎn)化為xml存儲了。具體實現(xiàn)大家看源代碼即可。未找到在silverlight中動態(tài)生成一個文件下載,和從用戶本地的系統(tǒng)中提取文件的方法,生成xml的文件存放在一個TextBox中,拷貝就可以。4.3撤銷及前進(jìn)有了上面的生成xml及載入xml的基礎(chǔ),就可以設(shè)計出一個支持撤銷和前進(jìn)功能的應(yīng)用了。有c/s編程經(jīng)驗的朋友對此一定不陌生,搞b/s開發(fā)的可能不太熟悉,這里簡單實現(xiàn),并說明一下思路。在內(nèi)存中定一個兩個堆棧(Stack),一個保存用于撤銷的xml集合,一個保存用于前進(jìn)的xml集合。當(dāng)出現(xiàn)下面的情況是,將流程當(dāng)前狀態(tài)的xml描述進(jìn)入出棧和入棧的動作。用戶進(jìn)行流程修改的時候,將修改后的xml描述壓入(Push)撤銷堆棧,并清空前進(jìn)堆棧。當(dāng)用戶點擊撤銷按鈕時,從撤銷堆棧彈出(pop)一個xm,使用這個xml來還原流程圖,同時將這個xml壓入前進(jìn)堆棧。當(dāng)用戶點擊前進(jìn)按鈕時,從前進(jìn)堆棧彈出(pop)一個xm,使用這個xml來還原流程圖,同時將這個xml壓入撤銷堆棧。也就是說兩個堆棧協(xié)同工作,就可以完成撤銷、前進(jìn)的功能了。另外撤銷前進(jìn)功能的xml存儲也可以有兩種方式,一種是增量存儲,也就是只存儲改變的部分,另一種的完全存儲,也就是存儲當(dāng)前整個流程圖的xm。對于第一種比較麻煩,對于第二種方式,系統(tǒng)中的函數(shù)已經(jīng)支持,所以采用第二種方式,就是比第一種方式存儲的xml長度大了一點。本章的內(nèi)容就結(jié)束了,請留下您的寶貴意見!后文再續(xù)!源代碼下載Silverlight構(gòu)建圖形化工作流程設(shè)計器(四)按計劃程序到這里就差不多結(jié)束了,但是有很多朋友希望能繼續(xù)完善這個程序,并增加有關(guān)工作流屬性的內(nèi)容,應(yīng)各位朋友要求,把這個系列繼續(xù)下去,并增加流程屬性的一些內(nèi)容。工作流在現(xiàn)代企業(yè)中廣泛應(yīng)用,本文不強求完成一個大而全的流程應(yīng)用,而是做一個框架類的東西,方按計劃程序到這里就差不多結(jié)束了,但是有很多朋友希望能繼續(xù)完善這個程序,并增加有關(guān)工作流屬性的內(nèi)容,應(yīng)各位朋友要求,把這個系列繼續(xù)下去,并增加流程屬性的一些內(nèi)容。工作流在現(xiàn)代企業(yè)中廣泛應(yīng)用,本文不強求完成一個大而全的流程應(yīng)用,而是做一個框架類的東西,方便進(jìn)行二次開發(fā)和擴展。大家從前面的內(nèi)容可以看出,本文很少直接貼代碼上來,而是主要側(cè)重于創(chuàng)作一個應(yīng)用程序過程中的遇到的問題以及解決問題的思路和方法(當(dāng)然也包括使用silverlight遇到的問題)。并且說明解決一個問題的多個方法之間的取舍原因。當(dāng)然這個原因不是絕對的,根據(jù)時間的推移和思路的延伸,我們還可以找到更加合適的解決問題的方法。在這個學(xué)習(xí)silverlight的過程中,希望和大家分享一下學(xué)習(xí)的心得,關(guān)于silverlight的,關(guān)于系統(tǒng)設(shè)計都有,只要使我覺得比較新鮮有趣的。也希望各位大蝦,新手多多指點。五美化需要美化的內(nèi)容有很多,目前想到并且打算做的部分有以下幾方面的內(nèi)容:規(guī)則使用帶箭頭的直線活動根據(jù)不同的活動類型顯示不同的形狀。界面調(diào)整5.1規(guī)則使用帶箭頭的直線在silverlight中的Line類沒有找設(shè)置箭頭的屬性,所以我們要自己做一個箭頭放在規(guī)則的尾部,能想到的有兩種方法:使用一個箭頭的圖片放在規(guī)則的尾部。自己編寫一個表示箭頭的類,并將這個類放在規(guī)則的尾部。對于這兩種方法,都涉及到一個問題,就是根據(jù)規(guī)則在不同的位置,箭頭的方向要隨著規(guī)則的變化角度做一個改變,以適應(yīng)規(guī)則的角度。第一種方法比較簡單,但是使用圖片一個是增加客戶端下載內(nèi)容的大小,還有不方便改變顯示的顏色,每次改變顏色都要換新的圖片,不方便。那么我們就自己寫一個表示圖片的類,方式在規(guī)則的尾部。這個類繼承自System.Windows.Controls.Canvas,我們叫它Arrowhead,Arrowhead類包含兩個子控件,分別是兩個Line(直線)類,這兩個直線類按照不同的角度排列,就可以形成一個箭頭,類似下面的圖形:

把這個類放在規(guī)則類的尾部,就形成了一個帶箭頭的直線,如下所示:

這樣用幾個對象合成了一個帶箭頭的直線。接下來的問題就是當(dāng)直線被拖轉(zhuǎn)進(jìn)行位移和旋轉(zhuǎn)的時候,箭頭也要隨著進(jìn)行相同的位移和旋轉(zhuǎn)。雖然我們不知道如何具體的實現(xiàn),但是經(jīng)過分析得知,這個旋轉(zhuǎn)的角度和直線的起始點坐標(biāo)位置和終點坐標(biāo)位置有關(guān),那么我們給箭頭類增加一個方法來設(shè)置這個變化,這個方法有兩個參數(shù)分別表示直線的起始和終結(jié)位置坐標(biāo),這樣一個帶箭頭的直線就完成了。這樣的過程可用下圖來表示:

接下來我們在規(guī)則類的xaml文件中這冊這個類,類似下面的代碼:<UserControx:Class="Shareidea.Web.UI.Contro.Workflow.Designer.Rule"

xmlns="/winfx/2006/xam/presentation"

xmlns:x="/winfx/2006/xam"

MouseEnter="UserContro_MouseEnter"

MouseLeave="UserContro_MouseLeave"

xmlns:Shareidea="clr-namespace:Shareidea.Web.UI.Contro.Workflow.Designer"

>其中最后一行xmlns:Shareidea="clr-namespace:Shareidea.Web.UI.Contro.Workflow.Designer"我們在當(dāng)前xaml中注冊了命名空間Shareidea.Web.UI.Contro.Workflow.Designer那么在當(dāng)前xaml文件中既可以使用類似于<Shareidea:ArrowheadName="endArrow"/>這樣的聲明來使用自定義類了。下面的代面具體表示了這樣的一個箭頭類,其中用到了數(shù)學(xué)公式的類,System.Math.Sin(double黨),這樣的一個類用來計算一個角度的Sin值,需要注意的是,我們平常講的30度的Sin不能直接作為參數(shù)傳遞,因為這個函數(shù)的參數(shù)是一個弧度值,而不是一個角度的值,需要做一個轉(zhuǎn)換,例如Math.PI*30/180.0,經(jīng)過這樣一個轉(zhuǎn)換,把角度30轉(zhuǎn)換成一個弧度值就可以了。publicclassArrowhead:System.Windows.Controls.Canvas

{

intarrowLenght=12;

intarrowAngle=30;

///<summary>

///箭頭的長度

///</summary>

ArrowLenght

{

get

{

returnarrowLenght;

}

set

{

arrowLenght=value;

}

}

///<summary>

///箭頭的與直線的夾角

///</summary>

ArrowAngle

{

get

{

returnarrowAngle;

}

set

{

arrowAngle=value;

}

}

LinelineLeft;

LinelineRight;

ZIndex

{

get

{

return(int)this.GetValue(Canvas.ZIndexProperty);

}

set

{

this.SetValue(Canvas.ZIndexProperty,value);

}

}

publicvoidSetAnge(PointbeginPoint,PointendPoint)

{

}

publicBrushStroke

{

get

{

returnlineRight.Stroke;

}

set

{

lineRight.Stroke=value;

lineLeft.Stroke=value;

}

}

publicdoubleStrokeThickness

{

set

{

lineRight.StrokeThickness=value;

lineLeft.StrokeThickness=value;

}

get

{

returnlineLeft.StrokeThickness;

}

}

voidSetAngleByDegree(doubledegreeLeft,doubledegreeRight)

{

doubleangleSi=Math.PI*degreeLeft/180.0;

doublex=System.Math.Sin(Math.PI*degreeLeft/180.0);

double央=System.Math.Sin(Math.PI*(90-degreeLeft)/180.0);

lineLeft.X2=-ArrowLenght*x;

lineLeft.Y2=-ArrowLenght*央;

x=System.Math.Sin(Math.PI*degreeRight/180.0);

央=System.Math.Sin(Math.PI*(90-degreeRight)/180.0);

lineRight.X2=ArrowLenght*x;

lineRight.Y2=-ArrowLenght*央;

}

///<summary>

///根據(jù)直線的起始點和結(jié)束點的坐標(biāo)設(shè)置箭頭的旋轉(zhuǎn)角度

///</summary>

///<="beginPoint"></param>

///<="endPoint"></param>

publicvoidSetAngleByPoint(PointbeginPoint,PointendPoint)

{

doublex=endPoint.X-beginPoint.X;

double央=endPoint.央-beginPoint.央;

doubleangle=System.Math.Atan(x/央)*180/Math.PI;

if(endPoint.央<beginPoint.央)

SetAngleByDegree((ArrowAngle+angle)-180,(ArrowAngle-angle)-180);

else

SetAngleByDegree(ArrowAngle+angle,ArrowAngle-angle);

}

publicArrowhead()

{

lineLeft=newLine();

lineRight=newLine();

this.Children.Add(lineLeft);

this.Children.Add(lineRight);

lineLeft.X1=0;

lineLeft.Y1=0;

lineRight.X1=0;

lineRight.Y1=0;

SetAngleByPoint(newPoint(0,0),newPoint(15,15));

}

}Silverlight構(gòu)建圖形化工作流程設(shè)計器(五)本文主要側(cè)重于創(chuàng)作一個應(yīng)用程序過程中的遇到的問題以及解決問題的思路和方法(當(dāng)然也包括使用silverlight遇到的問題)。并且說明解決一個問題的多個方法之間的取舍原因。當(dāng)然這個原因不是絕對的,根據(jù)時間的推移和思路的延伸,我們還可以找到更加合適的解決問題的方法本文主要側(cè)重于創(chuàng)作一個應(yīng)用程序過程中的遇到的問題以及解決問題的思路和方法(當(dāng)然也包括使用silverlight遇到的問題)。并且說明解決一個問題的多個方法之間的取舍原因。當(dāng)然這個原因不是絕對的,根據(jù)時間的推移和思路的延伸,我們還可以找到更加合適的解決問題的方法。在這個學(xué)習(xí)silverlight的過程中,希望和大家分享一下學(xué)習(xí)的心得,關(guān)于silverlight的,關(guān)于系統(tǒng)設(shè)計都有,只要使我覺得比較新鮮有趣的。也希望各位大蝦,新手多多指點。五美化5.2活動根據(jù)不同的活動類型顯示不同的形狀要是活動根據(jù)不同的類型顯示不同的形狀,我們也有幾種方法:根據(jù)類型不同,定義不同的圖形顯示根據(jù)類型不同,對現(xiàn)有的活動圖形進(jìn)行剪裁處理。第一種方法會給我們已有的類造成比較大的修改,因為涉及到圖形在移動時候需要對關(guān)聯(lián)的規(guī)則類進(jìn)行動態(tài)定位的問題。使用第二種方法去沒有這個問題,只需要動體的對活動類進(jìn)行剪裁處理就可以了?;顒宇愋陀幸韵聨追N:常規(guī)交互活動,也就是需要人工參與的活動。自動活動,沒有人工參與的活動,后臺自動完成。分支活動,包括與分支、或分支匯聚活動,包括與匯聚,或匯聚,投票匯聚。起始與終結(jié)活動當(dāng)我們給活動指定不同的類型時,希望顯示不同的活動形狀。對于常規(guī)交互活動,顯示矩形圖形,對于分支和匯聚活動顯示菱形,對于其他活動,顯示圓形。矩形和圓形分別用EllipseGeometry和RectangleGeometry類進(jìn)行裁減就可以了,對于菱形,需要使用PathGeometry類進(jìn)行裁減,這個類的使用有點復(fù)雜,需要定義多個轉(zhuǎn)折點。然后這些點圍成一個菱形。5.3給活動和規(guī)則增加配置界面為了給活動設(shè)置類型,我們需要給活動增加一個配置界面,具體還是增加一個用戶控件,xaml代碼如下:<UserControx:Class="Shareidea.Web.UI.Contro.Workflow.Setting.ActivitySetting"

xmlns="/winfx/2006/xam/presentation"

xmlns:x="/winfx/2006/xam"

MouseLeftButtonDown="UserContro_MouseLeftButtonDown"

MouseLeftButtonUp="UserContro_MouseLeftButtonUp"

MouseMove="UserContro_MouseMove"

>

<Gridx:Name="LayoutRoot">

<BorderBackground="Gold"CornerRadius="30">

<StackPaneVerticalAlignment="Top"Margin="20">

<GridShowGridLines="False">

<Grid.RowDefinitions>

<RowDefinitionHeight="30"></RowDefinition>

<RowDefinitionHeight="30"></RowDefinition>

</Grid.RowDefinitions>

<Grid.ColumnDefinitions>

<ColumnDefinitionWidth="60"></ColumnDefinition>

<ColumnDefinitionWidth="200"></ColumnDefinition>

</Grid.ColumnDefinitions>

<TextBlockText="活動名稱"VerticalAlignment="Center"HorizontalAlignment="Left"Grid.Column="0"Grid.Row="0"></TextBlock>

<TextBlockText="活動類型"VerticalAlignment="Center"HorizontalAlignment="Left"Grid.Column="0"Grid.Row="1"></TextBlock>

<TextBoxName="txtActivityName"Width="200"VerticalAlignment="Center"HorizontalAlignment="Left"Grid.Column="1"Grid.Row="0"></TextBox>

<ComboBoxName="cbActivityType"Width="200"VerticalAlignment="Center"HorizontalAlignment="Left"Grid.Column="1"Grid.Row="1">

<ComboBox.ItemTemplate>

<DataTemplate>

<StackPaneOrientation="Horizonta">

<TextBlockText="{BindingPath=Name}"Visibility="Collapsed"/>

<TextBlockText="{BindingPath=Text}"VerticalAlignment="Center"/>

</StackPane>

</DataTemplate>

</ComboBox.ItemTemplate>

</ComboBox>

</Grid>

<StackPaneVerticalAlignment="Center"HorizontalAlignment="Center"Margin="01000"Orientation="Horizonta">

<ButtonName="btnSave"Content="保存"Margin="0000"Width="60"Height="30"Click="btnSave_Click"></Button>

<ButtonName="btnClose"Content="關(guān)閉"Margin="10000"Width="60"Height="30"Click="btnClose_Click"></Button>

</StackPane>

</StackPane>

</Border>

</Grid>

</UserContro>上面的代碼有兩點需要介紹的:ComboBox控件。Silverlight2.0中沒有dropdownlist控件,但是有一個更加強大和靈活的ComboBox控件。ComboBox可以使用內(nèi)容模板的方式添加子元素(Item),我們可以使用任意一個silverlight控件作為ComboBox的子元素,這樣就給我們很大的靈活性,用來構(gòu)造復(fù)雜的下拉框內(nèi)容了??丶慕壎ㄕZ法。在上面的xaml代碼中,使用到了類似于<TextBlockText="{BindingPath=Name}"這樣的代碼,這個是silverlight的綁定語法。在后臺代碼中,使用下面的代碼進(jìn)行綁定publicActivitySetting()

{

InitializeComponent();

List<ActivityTypeItem>Cus=newList<ActivityTypeItem>();

Cus.Add(newActivityTypeItem("AND_BRANCH","與分支活動"));

Cus.Add(newActivityTypeItem("AND_MERGE","與匯聚活動"));

Cus.Add(newActivityTypeItem("AUTOMATION","常規(guī)自動活動"));

Cus.Add(newActivityTypeItem("COMPLETION","終結(jié)活動"));

Cus.Add(newActivityTypeItem("DUMMY","啞活動"));

Cus.Add(newActivityTypeItem("INITIA","初始化活動"));

Cus.Add(newActivityTypeItem("INTERACTION","常規(guī)交互活動"));

Cus.Add(newActivityTypeItem("OR_BRANCH","或分支"));

Cus.Add(newActivityTypeItem("OR_MERGE","或匯聚活動"));

Cus.Add(newActivityTypeItem("SUBPROCESS","子流程"));

Cus.Add(newActivityTypeItem("VOTE_MERGE","投票匯聚活動"));

cbActivityType.ItemsSource=Cus;

}

publicclassActivityTypeItem

{

publicstringName{get;set;}

publicstringText{get;set;}

publicActivityTypeItem(stringname,stringtext)

{

Name=name;

Text=text;

}

}對于規(guī)則的配置類似于上面的步驟,這里不再贅述。Silverlight構(gòu)建圖形化工作流程設(shè)計器(六)本章繼續(xù)美化工作,本章內(nèi)容相當(dāng)簡單,權(quán)當(dāng)一段流水賬好了。下一章的內(nèi)容將增加一個非常優(yōu)秀的用戶體驗功能,這個功能也是受到網(wǎng)友的啟發(fā)增加的,敬請關(guān)注。五美化本章內(nèi)容主要包括1、規(guī)則圖形支持曲線2、增加默認(rèn)初始化流程圖形3、支持鼠標(biāo)雙擊事件4、控件支持ToopTip5、自定義容器寬和高5.4規(guī)則圖形支持曲線本章繼續(xù)美化工作,本章內(nèi)容相當(dāng)簡單,權(quán)當(dāng)一段流水賬好了。下一章的內(nèi)容將增加一個非常優(yōu)秀的用戶體驗功能,這個功能也是受到網(wǎng)友的啟發(fā)增加的,敬請關(guān)注。五美化本章內(nèi)容主要包括1、規(guī)則圖形支持曲線2、增加默認(rèn)初始化流程圖形3、支持鼠標(biāo)雙擊事件4、控件支持ToopTip5、自定義容器寬和高5.4規(guī)則圖形支持曲線在前面的內(nèi)容中,用來表示規(guī)則類的圖形一條直線,當(dāng)有兩個規(guī)則互為反向規(guī)則時(這兩個規(guī)則的起始活動和結(jié)束活動正好對調(diào)),那么這兩個規(guī)則的直線就重疊在一起了,不好區(qū)別。所以在這里把這個直線改為曲線。用下圖來表示這個改變:

需要做幾個工作,首先在規(guī)則類(Rule.xaml)中,把表示直線類(Line)換成表示曲線的類Polyline,在前面的內(nèi)容中,我們使用兩個點來定位直線,在換成新的Polyline類后,這部分代碼不需要做大的改變,只需要在增加一個中間點,這個中間點表示曲線的轉(zhuǎn)折點,而這個轉(zhuǎn)折點的坐標(biāo)可以根據(jù)起始坐標(biāo)和終點坐標(biāo)而定,非常簡單。下面的代碼表示了我們新的定位規(guī)則曲線的方法。publicvoidSetRulePosition(PointbeginPoint,PointendPoint)

{

begin.SetValue(Canvas.LeftProperty,beginPoint.X);

begin.SetValue(Canvas.TopProperty,beginPoint.央);

end.SetValue(Canvas.LeftProperty,endPoint.X);

end.SetValue(Canvas.TopProperty,endPoint.央);

Pointp1=newPoint(beginPoint.X+beginPointRadius,beginPoint.央+beginPointRadius);

Pointp3=newPoint(endPoint.X+endPointRadius,endPoint.央+endPointRadius);

Pointp2=newPoint();

if(LineType==RuleLineType.Line)

{

p2=p1;

}

else

{

if(System.Math.Abs(p1.X-p3.X)<10)

{

p2=p1;

}

else

{

p2.X=p1.X;

p2.央=p3.央;

}

}

line.Points.Clear();

line.Points.Add(p1);

line.Points.Add(p2);

line.Points.Add(p3);

}另外在規(guī)則配置類中增加規(guī)則線條類型的配置信息就可以了。5.5增加默認(rèn)初始化流程圖形前面的程序在初始化時,容器面板是一片空白,這本章中增加一個初始化的流程圖形。代碼很簡單。voidcreateNewWorkFlow()

{

Activitybegin=newActivity(this);

begin.Type=ActivityType.INITIAL;

begin.ActivityName="開始";

Activityend=newActivity(this);

end.Type=ActivityType.COMPLETION;

end.ActivityName="結(jié)束";

Ruler=newRule(this);

AddActivity(begin);

AddActivity(end);

AddRule(r);

r.SetBeginActivity(begin);

r.SetEndActivity(end);

end.Position=newPoint(100,100);

SaveChange(NextOrPreAction.None);

}最后一段將當(dāng)前的配置保存在內(nèi)存中。5.6支持鼠標(biāo)雙擊事件Silverlight2.0中不支持鼠標(biāo)雙擊事件,不過這不影響我們使用現(xiàn)有的功能來捕獲鼠標(biāo)雙擊,網(wǎng)上有一篇文章說明了其中的原理,如下:/blogs/msnow/archive/2009/01/15/silverlight-tip-of-the-day-82-how-to-implement-double-click.aspx主要使用一個定時器來檢查鼠標(biāo)兩次點擊之間的時間差,如果這個時間差在一個指定的范圍內(nèi),那么這兩次點擊被認(rèn)為是一次鼠標(biāo)雙擊事件。當(dāng)在規(guī)則或者活動上面進(jìn)行鼠標(biāo)點擊時,將捕獲這個點擊事件,并且顯示規(guī)則或者屬性的編輯窗口。

5.7活動和規(guī)則類支持ToopTipToopTip比Html元素中的ToopTip在定制外觀方面強大多了,下面是程序中用到ToopTip的xaml代碼<ToolTipService.ToolTip>

<ToolTipName="ttActivityTip"Content="Turtle"FontWeight="Bold"VerticalOffset="10"

HorizontalOffset="10">

<ToolTip.Background>

<LinearGradientBrushStartPoint="0,0"EndPoint="0,1">

<GradientStopColor="White"

Offset="0"></GradientStop>

<GradientStopColor="DarkCyan"

Offset="0.8"></GradientStop>

</LinearGradientBrush>

</ToolTip.Background>

</ToolTip>

</ToolTipService.ToolTip>5.8自定義容器寬和高自定義寬和高用到了控件Slider,通過事件ValueChanged來動態(tài)改變?nèi)萜鲗ο蟮膶捄透?,沒有更多需要解釋的了。下章的內(nèi)容很精彩,不要錯過哦。Silverlight構(gòu)建圖形化工作流程設(shè)計器(七)本章包括兩部分內(nèi)容,一個是在活動類上拖拽鼠標(biāo)自動生成規(guī)則,另一個是網(wǎng)友的反饋,就是規(guī)則的端點不要在活動的中心,而要在活動的邊緣。五美化5.9使用鼠標(biāo)拖拽自動生成規(guī)則本章內(nèi)容將給系統(tǒng)增加一個非常好的用戶體驗功能。之前我們增加一個設(shè)置一個規(guī)則需要以下幾個步驟:點擊增加規(guī)則按鈕,添加一個規(guī)則到容器中本章包括兩部分內(nèi)容,一個是在活動類上拖拽鼠標(biāo)自動生成規(guī)則,另一個是網(wǎng)友的反饋,就是規(guī)則的端點不要在活動的中心,而要在活動的邊緣。五美化5.9使用鼠標(biāo)拖拽自動生成規(guī)則本章內(nèi)容將給系統(tǒng)增加一個非常好的用戶體驗功能。之前我們增加一個設(shè)置一個規(guī)則需要以下幾個步驟:點擊增加規(guī)則按鈕,添加一個規(guī)則到容器中。拖動規(guī)則的起始部分,關(guān)聯(lián)的一個活動。拖動規(guī)則的結(jié)尾部分,關(guān)聯(lián)到一個活動。雖然只需要動動鼠標(biāo),已經(jīng)很簡單了,但是還有沒有更簡單的呢?當(dāng)然有,當(dāng)鼠標(biāo)在活動的中心區(qū)按下,并拖動鼠標(biāo),那么會自動生成一個臨時規(guī)則,這個規(guī)則的開始活動自動關(guān)聯(lián)到剛才點擊的活動,臨時規(guī)則的結(jié)尾點隨鼠標(biāo)移動,這個過程用下圖來說明:

接下來來看一下為了完成以上功能需要做的工作有哪些。1.需要在活動上定出一個中心區(qū)域在活動的xaml文件中增加一個圓形圖,以規(guī)則的中心為中心點,為了看的清楚,這個中心區(qū)域使用黃色填充,透明度設(shè)為0.3。2.監(jiān)控中心區(qū)域的MouseLeftButtonDown事件當(dāng)鼠標(biāo)在中心區(qū)域按下時,自動生成一個臨時的規(guī)則,并將這個規(guī)則的起始活動設(shè)為當(dāng)前活動,把這個規(guī)則傳遞給第三步中的全局臨時規(guī)則,代碼如下:if(_container.CurrentTemporaryRule==nul)

{

_container.CurrentTemporaryRule=newRule(_container);

_container.CurrentTemporaryRule.IsTemporaryRule=true;

_container.AddRule(_container.CurrentTemporaryRule);

_container.CurrentTemporaryRule.SetBeginActivity(this);

_container.CurrentTemporaryRule.EndPointPosition=_container.CurrentTemporaryRule.BeginPointPosition;

_container.CurrentTemporaryRule.ZIndex=_container.NextMaxIndex;

}

1.在容器類中設(shè)置一個全局的臨時規(guī)則對象為了能夠在容器的層面捕獲這個自動生成的臨時規(guī)則,需要定義一個容器層面的規(guī)則引用。publicRuleCurrentTemporaryRule{get;set;}2.監(jiān)控容器的MouseMove和MouseLeftButtonUp當(dāng)鼠標(biāo)在容器上移動時,如果有臨時的規(guī)則類,那么設(shè)置規(guī)則的結(jié)束位置,代碼如下:privatevoidContainer_MouseMove(objectsender,MouseEventArgse)

{

if(CurrentTemporaryRule!=nul)

{

CurrentTemporaryRule.CaptureMouse();

CurrentTemporaryRule.EndPointPosition=e.GetPosition(CurrentTemporaryRule);

}

}當(dāng)放開鼠標(biāo)時,如果有臨時規(guī)則,那么檢查規(guī)則的結(jié)束位置是否關(guān)聯(lián)到活動,如果沒有關(guān)聯(lián)到任何活動,那么刪除這個臨時規(guī)則,如果有關(guān)聯(lián)到其他的活動,那么取消臨時定義。代碼如下:privatevoidContainer_MouseLeftButtonUp(objectsender,MouseButtonEventArgse)

{

if(CurrentTemporaryRule!=nul)

{

CurrentTemporaryRule.SimulateRulePointMouseLeftButtonUpEvent(RuleMoveType.End,CurrentTemporaryRule,e);

if(CurrentTemporaryRule.EndActivity==nul)

{

this.RemoveRule(CurrentTemporaryRule);

}

else

{

CurrentTemporaryRule.IsTemporaryRule=false;

}

CurrentTemporaryRule.ReleaseMouseCapture();

CurrentTemporaryRule=nul;

}

}通過以上的工作,我們就實現(xiàn)了本文開頭所說的部分。5.10設(shè)置規(guī)則的端點在活動的邊緣這個設(shè)置可以用下圖來說明。對于規(guī)則的短線設(shè)置在活動的邊緣,有兩種方式可以考慮。一種是找到規(guī)則和活動的相交的點(Point),如上圖中紅色圓圈部分所示另一個是規(guī)則出現(xiàn)的活動的固定的點上,如上圖藍(lán)色十字相交部分所示對于第一種情況,目前還沒有找到一個好的方法來定位這個相交點。對于第二種情況就稍微好處理一點了。我們只要處理兩個活動的中心點的相對位置,就可以設(shè)置規(guī)則的端點的位置,如下圖所示

另外當(dāng)規(guī)則為曲線時,程序還需要進(jìn)一步判斷,下一章里面將作進(jìn)一步改進(jìn)。本章內(nèi)容到此結(jié)束,下章將繼續(xù)根據(jù)網(wǎng)友意見修改,謝謝關(guān)注:)Silverlight構(gòu)建圖形化工作流程設(shè)計器(八)從這一版本開始,本程序正是命名為ShareDesiner.S本章主要是增強用戶體驗功能,包括:1、支持對象多選(包括鼠標(biāo)和鍵盤兩種方式,類似windows中選擇多個文件的方式)。2、支持選中的對象群組移動。3、支持選中的對象拷貝和粘貼(活動和規(guī)則)。4、支持更多鍵盤操作Ctr+A(全選),Ctr+C(拷貝),Ctr+V(粘貼),Ctr+Z(回退),De從這一版本開始,本程序正是命名為ShareDesiner.S本章主要是增強用戶體驗功能,包括:1、支持對象多選(包括鼠標(biāo)和鍵盤兩種方式,類似windows中選擇多個文件的方式)。2、支持選中的對象群組移動。3、支持選中的對象拷貝和粘貼(活動和規(guī)則)。4、支持更多鍵盤操作Ctr+A(全選),Ctr+C(拷貝),Ctr+V(粘貼),Ctr+Z(回退),Delete(刪除)。5、更多右鍵菜單。如果您沒有耐心繼續(xù)往下看了,請看上面的視頻教程吧。六增強的用戶體驗功能6.1支持選擇多個對象對于選擇多個對象,我們可以參考windows中選擇多個文件的方式。包括兩種方式:按住Ctrl鍵,然后用鼠標(biāo)一次點擊選擇的文件,被選中的文件以不同的顏色顯示。按下鼠標(biāo)左鍵,然后拖動鼠標(biāo),在屏幕上畫出一個矩形,處在矩形中的文件被選中,同時以不同的顏色顯示。我們給活動和規(guī)則增加一個屬性IsSelectd,表示對象是否被選中。如果被選中,那么背景顏色使用區(qū)別于沒有選中的對象顏色。如下圖所示:

同時,在容器類中增加一個屬性CurrentSelectedControlCollection,用以存儲當(dāng)前被選中的對象集合。對于第一種方法,在對象的MouseLeftButtonDown中編寫代碼,設(shè)置對象的IsSelected=!IsSelected,同時將對象加入到容器的CurrentSelectedControlCollection集合中。對于第二種方法,首先需要根據(jù)鼠標(biāo)在容器內(nèi)的拖拽動作畫出相應(yīng)的矩形,當(dāng)鼠標(biāo)松開時,遍歷當(dāng)前所有容器中的對象,檢查對象是否在鼠標(biāo)畫出的矩形區(qū)域內(nèi),如果在,那么設(shè)置對象的IsSelected=true,并將對象添加到容器的屬性CurrentSelectedControlCollection中即可。如下圖所示:

6.2支持多個選擇對象的群組移動在前面的內(nèi)容中,我們使用鼠標(biāo)拖動一個對象在容器中移動,這個動作只限于一個對象(一個活動,或者一個規(guī)則),當(dāng)用戶選擇多個對象的時候,希望對這個多個對象進(jìn)行同步的移動處理。我們可以在前面代碼的基礎(chǔ)上進(jìn)行擴展,對于一個對象,我們的代碼已經(jīng)支持了移動處理,如果有多個對象被選中,我們在移動其中一個對象時,需要計算出當(dāng)前移動的位移(x,y座標(biāo)),并把這個位移參數(shù)傳遞給容器對象,在容器對象中根據(jù)6.1中的內(nèi)容,遍歷當(dāng)前選中的對象,根據(jù)位移參數(shù)重新設(shè)置對象的位移即可。6.3對象的拷貝和粘貼單個對象支持被拷貝和粘貼,選中的群組對象也支持拷貝和粘貼。6.3.1對象拷貝對象靠別類似于windows系統(tǒng)中的拷貝文件,對于windows中的拷貝文件,我們得到了一個完全相同于源文件的備份。對于我們的系統(tǒng)來說,對象包括規(guī)則和活動,這兩種對象支持拷貝,為了支持拷貝,我們需要給對象增加一個拷貝的方法。這個方法放置在相應(yīng)對象的類中,就叫做Clone().在這個方法中,首先New了一個新的活動或者規(guī)則類,并把當(dāng)前對象有關(guān)的數(shù)據(jù)和位置信息復(fù)制給我們新創(chuàng)建的對象,這樣就得到了一個對象的拷貝。使用6.1中的方法,遍歷當(dāng)前所有選中的對象,對于每一個對象調(diào)用它的Clone方法,并把這些備份的對象放在在容器類的CopyElementCollectionInMemory屬性中,以便進(jìn)行粘貼操作。6.3.2對象粘貼有了6.3.1的對象拷貝,對象粘貼就相對簡單一點了。我們遍歷容器的CopyElementCollectionInMemory,對于容器中的每一個對象,設(shè)置它的位置信息,并添加到容器中即可。6.4支持更多的鍵盤操作為了使得用戶操作更加快捷、簡便,我們給系統(tǒng)增加了更多的鍵盤操作功能。包括Ctr+A:選中容器內(nèi)的所有對象Ctr+C:拷貝選中的對象到內(nèi)存中Ctr+V:粘貼內(nèi)存中的拷貝對象Ctr+Z:退回上一步Delete:刪除選中的對象Silverlight構(gòu)建圖形化工作流程設(shè)計器(九)六增強的用戶體驗功能6.5約束性檢查在用戶保存流程時,系統(tǒng)需要對用戶當(dāng)前配置的流程進(jìn)行一般性的約束檢查。這些約束性檢查包括以下部分:每個流程都必須有一個開始活動以及一個結(jié)束活動。開始活動不能有前驅(qū)活動,必須有至少一個后續(xù)活動。結(jié)束活動不能有后繼活動,必須至少有一個前驅(qū)活動。分支活動有且只有一個六增強的用戶體驗功能6.5約束性檢查在用戶保存流程時,系統(tǒng)需要對用戶當(dāng)前配置的流程進(jìn)行一般性的約束檢查。這些約束性檢查包括以下部分:每個流程都必須有一個開始活動以及一個結(jié)束活動。開始活動不能有前驅(qū)活動,必須有至少一個后續(xù)活動。結(jié)束活動不能有后繼活動,必須至少有一個前驅(qū)活動。分支活動有且只有一個前驅(qū)活動,并且必須至少有一個后續(xù)活動。匯聚活動有且只有一個后繼活動,并且必須至少有一個前驅(qū)活動。常規(guī)交互活動必須至少有一個前驅(qū)活動和后繼活動(常規(guī)交互活動默認(rèn)擁有或分支以及或匯聚活動的特性)。每個規(guī)則都必須有起始活動和終結(jié)活動。任何兩個規(guī)則的起始活動和終結(jié)活動不能都相同。通過以上程序檢查的流程符合一般性約束條件,但并不表明這是一個完全正確的流程。這些檢查只是一種編譯性檢查,不包含運行時的檢查。運行時檢查是指流程在運行過程中的一些約束性檢查。這些包括但不限于:規(guī)則條件的編寫運行時檢查。流程死循環(huán)檢查。等等。

6.6增加動畫效果使用System.Windows.Media.Animation命名空間中的相關(guān)類來設(shè)置動畫效果,本文中的動畫效果很簡單,在現(xiàn)實右鍵菜單時以及隱藏右鍵菜單時,采用漸進(jìn)的現(xiàn)實和隱藏。Xaml代碼如下:<StackPane.Resources>

<Storyboardx:Name="sbShowMenu">

<DoubleAnimationFrom="0"To="170"Duration="00:00:0.2"

Storyboard.TargetName="spContentMenu"

Storyboard.TargetProperty="Height">

<DoubleAnimation.EasingFunction>

<CircleEaseEasingMode="EaseIn"/>

</DoubleAnimation.EasingFunction>

</DoubleAnimation>

</Storyboard>

<Storyboardx:Name="sbCloseMenu">

<DoubleAnimationFrom="170"To="0"Duration="00:00:0.2"

Storyboard.TargetName="spContentMenu"

Storyboard.TargetProperty="Height">

<DoubleAnimation.EasingFunction>

<CircleEaseEasingMode="EaseIn"/>

</DoubleAnimation.EasingFunction>

</DoubleAnimation>

</Storyboard>

<

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論