Silverlight Blend动画设计系列八:拖放(Drag-Drop)操作与拖放行为(DragBehavior)
在Silverlight中自身并沒有提供拖放功能的相關(guān)實現(xiàn),要實現(xiàn)拖放功能得借助其事件支持(MouseLeftButtonDown、MouseLeftButtonUp和MouseMove)來完成,實際應(yīng)用中我們可以通過行為(Behavior)特性將拖放操作封裝為行為,這樣可達(dá)到代碼復(fù)用的效果。而在Blend中則直接提供了拖放操作行為,它位于Microsoft.Expression.Interactions.dll的Microsoft.Expression.Interactivity.Layout名稱空間下。
?
Silverlight中的拖放操作通常是使用事件驅(qū)動動態(tài)定位對象的坐標(biāo)來實現(xiàn),首先來看看如何通過代碼的可編程方式在Silverlight中實現(xiàn)拖放操作,如下代碼塊:
private?void?OnMouseLeftButtonDown(object?sender,?MouseButtonEventArgs?e){
????FrameworkElement?element?=?sender?as?FrameworkElement;
????MousePosition?=?e.GetPosition(null);
????IsMouseCaptured?=?true;
????element.CaptureMouse();
????element.Cursor?=?Cursors.Hand;
}
private?void?OnMouseLeftButtonUp(object?sender,?MouseButtonEventArgs?e)
{
????FrameworkElement?element?=?sender?as?FrameworkElement;
????IsMouseCaptured?=?false;
????element.ReleaseMouseCapture();
????MousePosition.X?=?MousePosition.Y?=?0;
????element.Cursor?=?null;
}
private?void?OnMouseMove(object?sender,?MouseEventArgs?e)
{
????FrameworkElement?element?=?sender?as?FrameworkElement;
????if?(IsMouseCaptured)
????{
????????double?Y?=?e.GetPosition(null).Y?-?MousePosition.Y;
????????double?X?=?e.GetPosition(null).X?-?MousePosition.X;
????????X?=?X?+?(double)element.GetValue(Canvas.LeftProperty);
????????Y?=?Y?+?(double)element.GetValue(Canvas.TopProperty);
????????element.SetValue(Canvas.LeftProperty,?X);
????????element.SetValue(Canvas.TopProperty,?Y);
????????MousePosition?=?e.GetPosition(null);
????}
}
?
如上定義好的三個方法實現(xiàn)了對象的拖放算法,實際應(yīng)用中只需要將需要進(jìn)行拖放移動的對象分別添加MouseLeftButtonDown、MouseLeftButtonUp和MouseMove事件處理就行了。如下示例代碼:
attachedElement.MouseLeftButtonDown?+=?(s,?e)?=>?OnMouseLeftButtonDown(s,?e);attachedElement.MouseLeftButtonUp?+=?(s,?e)?=>?OnMouseLeftButtonUp(s,?e);
attachedElement.MouseMove?+=?(s,?e)?=>?OnMouseMove(s,?e);
?
按照常規(guī)做法我們會將以上相關(guān)方法的實現(xiàn)封裝為一個基類以達(dá)到復(fù)用的目的,但本文不推薦使用基類去封裝拖放行為,因為Silverlight有專門用于處理對象行為的特性-Behaviors。在Silverlight中System.Windows.Interactivity命名空間下提供了行為的基礎(chǔ)框架,我們可以進(jìn)行自由的擴(kuò)展行為以實現(xiàn)自己的不同需求。安裝Blend后可以在安裝目錄下找到Microsoft.Expression.Interactivity.dll這個庫,這個庫提供了一些比較常用的集中行為擴(kuò)展,在Blend中通過“窗口”--“資產(chǎn)”打開資產(chǎn)面板,選擇行為資產(chǎn)就可以查看到Silverlight 3中所提供的擴(kuò)展行為,如下圖:
?
?
我們可以將上面實現(xiàn)對象拖放的功能封裝為行為以達(dá)到代碼復(fù)用,在Blend中通過“文件”--“新建”菜單項可打開新建對象對話框。
?
Blend新建向?qū)?chuàng)建的行為提供了一套行為模板,如下代碼塊:
public?class?Behavior1?:?Behavior<DependencyObject>{
????public?Behavior1()
????{
????????//?在此點下面插入創(chuàng)建對象所需的代碼。
????????//
????????//?下面的代碼行用于在命令
????????//?與要調(diào)用的函數(shù)之間建立關(guān)系。如果您選擇
????????//?使用?MyFunction?和?MyCommand?的已注釋掉的版本,而不是創(chuàng)建自己的實現(xiàn),
????????//?請取消注釋以下行并添加對?Microsoft.Expression.Interactions?的引用。
????????//
????????//?文檔將向您提供簡單命令實現(xiàn)的示例,
????????//?您可以使用該示例,而不是使用?ActionCommand?并引用?Interactions?程序集。
????????//
????????//this.MyCommand?=?new?ActionCommand(this.MyFunction);
????}
????protected?override?void?OnAttached()
????{
????????base.OnAttached();
????????//?插入要在將?Behavior?附加到對象時運行的代碼。
????}
????protected?override?void?OnDetaching()
????{
????????base.OnDetaching();
????????//?插入要在從對象中刪除?Behavior?時運行的代碼。
????}
????/*
????public?ICommand?MyCommand
????{
????????get;
????????private?set;
????}
?????
????private?void?MyFunction()
????{
????????//?插入要在從對象中刪除?Behavior?時運行的代碼。
????}
????*/
}
?
要實現(xiàn)自定義行為通過此行為模板進(jìn)行自我擴(kuò)展就行了,位于System.Windows.Interactivity中的Behavior提供了將行為或命令進(jìn)行封裝以達(dá)到可進(jìn)行附加到其他的一個對象上,需要注意的是自定義行為默認(rèn)繼承Behavior<DependencyObject>,使用DependencyObject類型的行為是不能訪問對象的鼠標(biāo)事件的,如果要訪問鼠標(biāo)操作的事件,可以使用具體的UI組件類型或者直接使用UI元素基類UIElement。
?
下面為將本篇前面實現(xiàn)對象拖放功能的代碼進(jìn)行了行為的封裝,完整代碼如下:
///?<summary>///?Behavior:封裝行為和命令,便于附加到對象中。
///?DependencyObject:不能實現(xiàn)訪問鼠操作事件
///?UIElement:可訪問鼠標(biāo)事件
///?</summary>
public?class?DragBehavior?:?Behavior<UIElement>
{
????private?UIElement?attachedElement;
????private?UserControl?parent;
????private?bool?IsMouseCaptured;
????private?Point?MousePosition;
????protected?override?void?OnAttached()
????{
????????attachedElement?=?this.AssociatedObject;
????????parent?=?Application.Current.RootVisual?as?UserControl;
????????attachedElement.MouseLeftButtonDown?+=?(s,?e)?=>?OnMouseLeftButtonDown(s,?e);
????????attachedElement.MouseLeftButtonUp?+=?(s,?e)?=>?OnMouseLeftButtonUp(s,?e);
????????attachedElement.MouseMove?+=?(s,?e)?=>?OnMouseMove(s,?e);
????}
????private?void?OnMouseMove(object?sender,?MouseEventArgs?e)
????{
????????FrameworkElement?element?=?sender?as?FrameworkElement;
????????if?(IsMouseCaptured)
????????{
????????????double?Y?=?e.GetPosition(null).Y?-?MousePosition.Y;
????????????double?X?=?e.GetPosition(null).X?-?MousePosition.X;
????????????X?=?X?+?(double)element.GetValue(Canvas.LeftProperty);
????????????Y?=?Y?+?(double)element.GetValue(Canvas.TopProperty);
????????????element.SetValue(Canvas.LeftProperty,?X);
????????????element.SetValue(Canvas.TopProperty,?Y);
????????????MousePosition?=?e.GetPosition(null);
????????}
????}
????private?void?OnMouseLeftButtonUp(object?sender,?MouseButtonEventArgs?e)
????{
????????FrameworkElement?element?=?sender?as?FrameworkElement;
????????IsMouseCaptured?=?false;
????????element.ReleaseMouseCapture();
????????MousePosition.X?=?MousePosition.Y?=?0;
????????element.Cursor?=?null;
????}
????private?void?OnMouseLeftButtonDown(object?sender,?MouseButtonEventArgs?e)
????{
????????FrameworkElement?element?=?sender?as?FrameworkElement;
????????MousePosition?=?e.GetPosition(null);
????????IsMouseCaptured?=?true;
????????element.CaptureMouse();
????????element.Cursor?=?Cursors.Hand;
????}
????protected?override?void?OnDetaching()
????{
????????base.OnDetaching();
????}
}
?
通過行為特性將對象的拖放功能進(jìn)行封裝以達(dá)到復(fù)用的目的,以上就全部實現(xiàn)了這個功能,測試可通過Ctrol+Shift+B編譯項目,然后通過“資產(chǎn)”面板就可以發(fā)現(xiàn)以上自定義擴(kuò)展的拖放行為。
?
使用行為非常簡單,打開Blend的資源面板中,選中需要使用的行為,將其拖放到要使用該行為的對象(Blend中設(shè)計的界面對象)上就行了。其實在Blend也提供了拖放行為:MouseDragElementBehavior,直接使用這個行為和本篇所介紹的實現(xiàn)達(dá)到的是同樣的效果。以下為分別使用這兩種行為所對應(yīng)生成的XAML編碼:
?
<UserControl????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
????xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"?
????xmlns:local="clr-namespace:DragBehavior"
????xmlns:il="clr-namespace:Microsoft.Expression.Interactivity.Layout;assembly=Microsoft.Expression.Interactions"
????x:Class="DragBehavior.MainControl"
????Width="800"?Height="600">
????<Canvas?x:Name="LayoutRoot"?Background="White">
????????<Rectangle?Fill="#FFFF0000"?Stroke="#FF000000"?Height="100"?Width="100"?Canvas.Left="100"?Canvas.Top="100">
????????????<i:Interaction.Behaviors>
????????????????<il:MouseDragElementBehavior/>
????????????</i:Interaction.Behaviors>
????????</Rectangle>
????????<Ellipse?Fill="#FF0000FF"?Stroke="#FF000000"?Height="100"?Width="100"?Canvas.Top="219"?Canvas.Left="397">
????????????<i:Interaction.Behaviors>
????????????????<local:DragBehavior/>
????????????</i:Interaction.Behaviors>
????????</Ellipse>
????</Canvas>
</UserControl>
?
?
推薦資源:
Expression Blend實例中文教程(9) - 行為快速入門Behaviors
Silverlight中實現(xiàn)強壯的、可復(fù)用的拖放行為?
Silverlight & Blend動畫設(shè)計系列文章
MSDN:http://msdn.microsoft.com/zh-cn/library/cc189090(VS.95).aspx
http://www.silverlight.net/learn/quickstarts/animations/
?
版權(quán)說明
? 本文屬原創(chuàng)文章,歡迎轉(zhuǎn)載且注明文章出處,其版權(quán)歸作者和博客園共有。??
? 作??????者:Beniao
?文章出處:http://beniao.cnblogs.com/? 或? http://www.cnblogs.com/
?
posted on 2018-10-21 13:36 NET未來之路 閱讀(...) 評論(...) 編輯 收藏轉(zhuǎn)載于:https://www.cnblogs.com/lonelyxmas/p/9824761.html
總結(jié)
以上是生活随笔為你收集整理的Silverlight Blend动画设计系列八:拖放(Drag-Drop)操作与拖放行为(DragBehavior)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: js中的target与currentTa
- 下一篇: 不重复验证码