版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年西安旅游股份有限公司招聘模擬筆試試題及答案解析
- 2025廣西旅發(fā)集團(tuán)廣西自貿(mào)區(qū)醫(yī)院管理有限公司招5人考試備考題庫及答案解析
- 2025年亳州渦陽縣人力資源和社會保障局公開招募青年就業(yè)見習(xí)人員備考筆試題庫及答案解析
- 2025廣西壯族自治區(qū)人民醫(yī)院防城港醫(yī)院防城港市第一人民醫(yī)院緊急招聘超聲醫(yī)學(xué)科前臺登記員2人參考考試試題及答案解析
- 2025山東濟(jì)南市平陰豐源炭素有限責(zé)任公司招聘29人參考考試題庫及答案解析
- 2025中國信托業(yè)保障基金有限責(zé)任公司招聘參考考試試題及答案解析
- 2026年南昌大學(xué)附屬口腔醫(yī)院高層次人才招聘備考筆試題庫及答案解析
- 2025云南玉溪數(shù)字資產(chǎn)管理有限公司市場化選聘中層管理人員招聘3人備考筆試題庫及答案解析
- 網(wǎng)店顧問合同范本
- 網(wǎng)絡(luò)轉(zhuǎn)移協(xié)議書
- 2025年及未來5年市場數(shù)據(jù)中國拖拉機制造市場競爭態(tài)勢及投資戰(zhàn)略規(guī)劃研究報告
- 廣東省廣州市越秀區(qū)2024-2025學(xué)年八年級上學(xué)期期末考試英語試題
- 地震波速反演方法-洞察及研究
- 百年未有之大變局課件
- 2025年時事政治考試100題及答案
- 應(yīng)急救援電源
- 電力行業(yè)電力工程設(shè)計師崗位招聘考試試卷及答案
- 2025年北京市建筑施工作業(yè)人員安全生產(chǎn)知識教育培訓(xùn)考核試卷E卷及答案
- 中鐵群安員培訓(xùn)
- 2024年云南省第一人民醫(yī)院招聘考試真題
- 2025急性高甘油三酯血癥胰腺炎康復(fù)期多學(xué)科管理共識解讀
評論
0/150
提交評論