我們現在知道 thumb ,可以讓用戶自行拖動其在 canvas上移動,在這個而基礎上 我們可以試着往流程圖方向靠近一下。
我們知道,流程圖,都是一個一個的流程塊,然后用線連起來的,這一個一個的流程塊可能會有各種各樣的形狀, 比如長方形,菱形
這很簡單 ,只需要設置 thumb使用不同的控件模板就ok.
在 界面上 放置了多個 thumb之后, 每一個都是需要響應dragDelta事件 才可以實現拖動的, 這樣的話 就基本要給每一個thumb寫上各自的 dragDelta處理方法。 如果這樣子,那代碼就開始臃腫了。
所以 針對可以拖動的滑塊,可以開發子類 如下:
public class MoveThumb :Thumb { public MoveThumb() { this.DragDelta += MoveThumb_DragDelta; } public void MoveThumb_DragDelta(object sender, DragDeltaEventArgs e) { Thumb myThumb = (Thumb )sender; double nTop = Canvas .GetTop(myThumb) + e.VerticalChange; double nLeft = Canvas .GetLeft(myThumb) + e.HorizontalChange; Canvas.SetTop(myThumb, nTop); Canvas.SetLeft(myThumb, nLeft); } }
前台
<Window.Resources> <ControlTemplate x :Key="rec"> <Rectangle Fill ="Gray" Width="70" Height="50"></ Rectangle> </ControlTemplate> <ControlTemplate x :Key="ell"> <Ellipse Fill ="Gray" Width="70" Height="70"></ Ellipse> </ControlTemplate> </Window.Resources > <Grid > <Canvas Background ="AliceBlue" HorizontalAlignment="Left" Height="412" Margin="10,10,0,0" VerticalAlignment="Top" Width="522"> <local: MoveThumb Canvas.Left="50" Canvas.Top="50" Template="{StaticResource rec}"></local: MoveThumb> <local: MoveThumb Canvas.Left="140" Canvas.Top="50" Template="{StaticResource ell}"></local: MoveThumb> <local: MoveThumb Canvas.Left="250" Canvas.Top="50" Template="{StaticResource ell}"></local: MoveThumb> </Canvas> </Grid >
效果如下

是的,我們現在的這些滑塊 都可以在畫布上滑動了。但是 上面代碼的的寫法有不好的地方在於,thumb塊不是內容控件,他是不可以在內部放東西的。而我們的這一系列功能是為了給以后的流程圖做鋪墊, 而流程圖的塊里面 到時候是需要實際放上我們的activity活動來作為執行的。所以我們應該 換一種寫法思路來實現目前的這個效果。
我們應該改造成 讓界面上的都是內容控件,而這些內容控件的controlTemplate則使用上面開發的 MoveThumb。這樣一來 代碼還是要有不少變動的。
頁面元素變為
<ContentControl Canvas.Left ="50" Canvas.Top="50" Template="{StaticResource thumbItemTemplate}"> <Ellipse Width ="50" Height="50" Fill="OrangeRed" IsHitTestVisible="False"></ Ellipse> </ContentControl>
<ControlTemplate x :Key="rawThumbTemplate" TargetType="Thumb"> <Rectangle Fill ="Transparent"></Rectangle> </ControlTemplate> <ControlTemplate x :Key="thumbItemTemplate" TargetType="ContentControl"> <Grid DataContext ="{Binding RelativeSource ={RelativeSource TemplatedParent}}"> <!--這里的放置順序還是有講究的--> <local: MoveThumb Template="{ StaticResource rawThumbTemplate}" Cursor="SizeAll"></ local:MoveThumb > <ContentPresenter Content ="{TemplateBinding Content}"></ContentPresenter> </Grid> </ControlTemplate>
注意到 我們這邊綁定了 模板中 MoveThumb的datacontext為使用這個模板的元素,這樣moveThumb代碼修改如下
public void MoveThumb_DragDelta( object sender, DragDeltaEventArgs e) { Control item = this.DataContext as Control; if(item!= null) { double left = Canvas.GetLeft(item); double top = Canvas.GetTop(item); Canvas.SetTop(item,top+e.VerticalChange); Canvas.SetLeft(item,left+e.HorizontalChange); } }
就可以通過 DataContext獲取 實際需要在畫板上位移的元素。 運行出來的效果是一樣的。只不過我們界面上的元素成為了 contentControl,這樣子以后 像其內部放東西 就成為可能。