Silverlight Blend動畫設計系列八:拖放(Drag-Drop)操作與拖放行為(DragBehavior)

Silverlight & Blend動畫設計系列八:拖放(Drag-Drop)操作與拖放行為(DragBehavior)
原文:Silverlight & Blend動畫設計系列八:拖放(Drag-Drop)操作與拖放行為(DragBehavior)

  在Silverlight中自身并沒有提供拖放功能的相關實現,要實現拖放功能得借助其事件支持(MouseLeftButtonDown、MouseLeftButtonUp和MouseMove)來完成,實際應用中我們可以通過行為(Behavior)特性將拖放操作封裝為行為,這樣可達到代碼復用的效果。而在Blend中則直接提供了拖放操作行為,它位于Microsoft.Expression.Interactions.dll的Microsoft.Expression.Interactivity.Layout名稱空間下。

?

  Silverlight中的拖放操作通常是使用事件驅動動態定位對象的坐標來實現,首先來看看如何通過代碼的可編程方式在Silverlight中實現拖放操作,如下代碼塊:

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);
????}
}

?

  如上定義好的三個方法實現了對象的拖放算法,實際應用中只需要將需要進行拖放移動的對象分別添加MouseLeftButtonDown、MouseLeftButtonUp和MouseMove事件處理就行了。如下示例代碼:

attachedElement.MouseLeftButtonDown?+=?(s,?e)?=>?OnMouseLeftButtonDown(s,?e);
attachedElement.MouseLeftButtonUp?
+=?(s,?e)?=>?OnMouseLeftButtonUp(s,?e);
attachedElement.MouseMove?
+=?(s,?e)?=>?OnMouseMove(s,?e);

?

  按照常規做法我們會將以上相關方法的實現封裝為一個基類以達到復用的目的,但本文不推薦使用基類去封裝拖放行為,因為Silverlight有專門用于處理對象行為的特性-Behaviors。在Silverlight中System.Windows.Interactivity命名空間下提供了行為的基礎框架,我們可以進行自由的擴展行為以實現自己的不同需求。安裝Blend后可以在安裝目錄下找到Microsoft.Expression.Interactivity.dll這個庫,這個庫提供了一些比較常用的集中行為擴展,在Blend中通過“窗口”--“資產”打開資產面板,選擇行為資產就可以查看到Silverlight 3中所提供的擴展行為,如下圖: 

        ?

?

  我們可以將上面實現對象拖放的功能封裝為行為以達到代碼復用,在Blend中通過“文件”--“新建”菜單項可打開新建對象對話框。

        

?

  Blend新建向導創建的行為提供了一套行為模板,如下代碼塊:

public?class?Behavior1?:?Behavior<DependencyObject>
{
????
public?Behavior1()
????{
????????
//?在此點下面插入創建對象所需的代碼。

????????
//
????????
//?下面的代碼行用于在命令
????????
//?與要調用的函數之間建立關系。如果您選擇
????????
//?使用?MyFunction?和?MyCommand?的已注釋掉的版本,而不是創建自己的實現,
????????
//?請取消注釋以下行并添加對?Microsoft.Expression.Interactions?的引用。
????????
//
????????
//?文檔將向您提供簡單命令實現的示例,
????????
//?您可以使用該示例,而不是使用?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?時運行的代碼。
????}
????
*/
}

?

  要實現自定義行為通過此行為模板進行自我擴展就行了,位于System.Windows.Interactivity中的Behavior提供了將行為或命令進行封裝以達到可進行附加到其他的一個對象上,需要注意的是自定義行為默認繼承Behavior<DependencyObject>,使用DependencyObject類型的行為是不能訪問對象的鼠標事件的,如果要訪問鼠標操作的事件,可以使用具體的UI組件類型或者直接使用UI元素基類UIElement。

?

  下面為將本篇前面實現對象拖放功能的代碼進行了行為的封裝,完整代碼如下:

///?<summary>
///?Behavior:封裝行為和命令,便于附加到對象中。
///?DependencyObject:不能實現訪問鼠操作事件
///?UIElement:可訪問鼠標事件
///?</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();
????}
}

?

  通過行為特性將對象的拖放功能進行封裝以達到復用的目的,以上就全部實現了這個功能,測試可通過Ctrol+Shift+B編譯項目,然后通過“資產”面板就可以發現以上自定義擴展的拖放行為。

        

?

  使用行為非常簡單,打開Blend的資源面板中,選中需要使用的行為,將其拖放到要使用該行為的對象(Blend中設計的界面對象)上就行了。其實在Blend也提供了拖放行為:MouseDragElementBehavior,直接使用這個行為和本篇所介紹的實現達到的是同樣的效果。以下為分別使用這兩種行為所對應生成的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中實現強壯的、可復用的拖放行為?

  Silverlight & Blend動畫設計系列文章

  MSDN:http://msdn.microsoft.com/zh-cn/library/cc189090(VS.95).aspx

  http://www.silverlight.net/learn/quickstarts/animations/

?

版權說明

? 本文屬原創文章,歡迎轉載且注明文章出處,其版權歸作者和博客園共有。??

? 作??????者:Beniao

?文章出處:http://beniao.cnblogs.com/? 或? http://www.cnblogs.com/

?

posted on 2018-10-21 13:36 NET未來之路 閱讀(...) 評論(...) 編輯 收藏

轉載于:https://www.cnblogs.com/lonelyxmas/p/9824761.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/450950.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/450950.shtml
英文地址,請注明出處:http://en.pswp.cn/news/450950.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

mysql查詢顯示行號

見&#xff1a;http://blog.csdn.net/muzizhuben/article/details/49449853 使用mysql查詢顯示行號&#xff0c;沒有像oracle這么方便。 不過也可以通過設定變量顯示行號&#xff0c;例如&#xff1a; -- 生成 行號 select r:r1 as rowno , a.* from my_tb a ,(select r:0) b …

scanf 用法大全

關于標準庫函數scanf論壇上很多人對scanf的不太了解&#xff0c;導致程序出錯&#xff0c;我想把scanf的具體用法貼出來&#xff0c;希望大家可以共同進步&#xff0c;有什么不對的地方可以提出來。int scanf(char *format&#xff0c;...);這應該是scanf的標準形式。先說說關于…

深入了解Spring IoC

IoC全稱Inversion of Control即控制反轉&#xff0c;它還有一個別名依賴注入。spring利用Ioc容器幫我們自動構建對象及注入依賴對象&#xff0c;減少了對象構建與業務代碼的耦合&#xff0c;使得我們能夠更加高效愉快的寫bug&#x1f41e;了(&#xffe3;▽&#xffe3;)"…

軟文營銷實戰記錄

最近拜讀了徐茂權老師的《 網絡營銷決勝武器(第2版)》&#xff0c;下面會梳理書中的內容&#xff0c;記錄下以后可能會用到的軟文營銷的技巧。 一、軟文載體 1、平面媒體軟文&#xff1a;報紙、期刊。 2、非正式出版的基于印刷、打印形式載體的軟文&#xff1a;企業印刷的宣傳冊…

oracle中rownum和row_number()的區別

見&#xff1a;http://www.jb51.net/article/65960.htm row_number()over(partition by col1 order by col2)表示根據col1分組&#xff0c;在分組內部根據col2排序&#xff0c;而此函數計算的值就表示每組內部排序后的順序編號&#xff08;組內連續的唯一的&#xff09;。 與ro…

java類加載順序

在java中類的加載、初始化都是在程序運行期完成的&#xff0c;雖然會稍微增加開銷&#xff0c;但是卻很大的增加了靈活性&#xff0c;我們可用在運行期間動態的去網絡或其他地方加載一個二進制流來作為程序代碼的一部分。接下來我們簡單介紹下java類加載過程。 從上圖中我們可…

dealloc不調用的情況

2019獨角獸企業重金招聘Python工程師標準>>> 1、沒有停止定時器 - (void)dealloc { [_timer invalidate]; _timer nil; } 2、VC中有代理Delegate&#xff0c;需要設置delegate的時候&#xff0c;設置為weak property (nonatomic,weak) id<ZoeEatDe…

day10-列表生成式

列表生成式即List Comprehensions&#xff0c;是Python內置的非常簡單卻強大的可以用來創建list的生成式。 1、生成一個列表 a [i for i in range(1,100) if i%21]print(list(a))或print(a)[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, …

jrebel、JavaRebel

見&#xff1a;https://baike.baidu.com/item/jrebel/1115725?fraladdin JRebel是一套JavaEE開發工具。中文名jrebel屬 性JavaEE開發工具資 費收費軟件作 用Jrebel 可快速實現熱部署JRebel是一套JavaEE開發工具。JRebel允許開發團隊在有限的時間內完成更多的任務修正…

自己寫函數庫

大家現在寫 程序&#xff0c;是不是都是用新唐提供的函數庫&#xff1f;在體驗 開發板的一開始&#xff0c;我也是使用函數庫&#xff0c;畢竟這個太方便了。可是有一天&#xff0c;我發現一個只使用時鐘和IO以及 調試 串口的程序居然查過了16k的時候&#xff0c;我震驚了&…

[MicroPython]stm32f407控制DS18B20檢測溫度

2019獨角獸企業重金招聘Python工程師標準>>> 1.實驗目的 1. 學習在PC機系統中擴展簡單I/O 接口的方法。 2. 進一步學習編制數據輸出程序的設計方法。 3. 學習DS18B20的接線方法&#xff0c;并利用DS18B20檢測當前溫度。 2.所需元器件 F407Micropython開發板…

帶你理解Spring AOP

AOP概述 在我們的日常開發中&#xff0c;除了正常業務邏輯外&#xff0c;還可能經常會需要在業務邏輯的特定位置加入日志&#xff0c;以便于調試和問題分析。但是這種插入日志的邏輯和業務邏輯間并不存在連續性和依賴性&#xff0c;這種邏輯侵入隨著項目的不斷發展&#xff0c…

10.20隨筆

ES6 ECMAScript是一種由Ecma國際&#xff08;前身為歐洲計算機制造商協會,英文名稱是European Computer Manufacturers Association&#xff09;通過ECMA-262標準化的腳本程序設計語言。 這種語言在萬維網上應用廣泛&#xff0c;它往往被稱為JavaScript或JScript&#xff0c;但…

極客招募令!兄弟杯區塊鏈極客競技大賽在上海等您來戰!

據悉&#xff0c;由國內首家區塊鏈技術社區區塊鏈兄弟主辦&#xff0c;旺鏈科技、離子鏈、中國云體系產業創新戰略聯盟、無退社區、指旺金科等單位強力支持&#xff0c;HiBlock區塊鏈社區、火球財經、布洛克財經、海豚區塊鏈、區塊網等百家技術社區和媒體通力合作的兄弟杯區塊鏈…

Java中Web程序修改配置文件不重啟服務器的方法

見&#xff1a;http://blog.sina.com.cn/s/blog_69398ed9010191jg.html 另&#xff1a;http://ekisstherain.iteye.com/blog/1701463 jrebel 、JavaRebel是什么&#xff0c;見另一博客&#xff1a;jrebel/JavaRebel 開發環境 1. JDK 2. MyEclipse 3. Tomcat 4. Struts2 5.…

ffmpeg-0.6.3 移植到 windows 開源代碼

ffmpeg-0.6.3開源編碼解碼庫&#xff0c;從linux下移植到windows vs2005&#xff0c;全部開源。 需要 Intel C Compile 和 開源的SDL庫支持&#xff0c;由于 Intel C Compile支持C99語法&#xff0c;所以源代碼改動很小很小。 主要的修改 1&#xff1a;添加了linux中有而wind…

一起嘮嘮分布式鎖

&#xff08;1&#xff09;分布式鎖和分布式事務的區別 1.分布式鎖是在集群環境下&#xff0c;用來控制不同機器對全局共享資源的訪問。 2.分布式事務是在集群環境下&#xff0c;用來保證全局事務的一致性&#xff0c;保證多個數據庫的數據整體上能正確的從一個一致性狀態轉到…

luogu2577/bzoj1899 午餐 (貪心+dp)

首先&#xff0c;應該盡量讓吃飯慢的排在前面&#xff0c;先按這個排個序 然后再來決定每個人到底去哪邊 設f[i][j]是做到了第i個人&#xff0c;然后1號窗口目前的總排隊時間是j&#xff0c;目前的最大總時間 有這個i和j的話&#xff0c;再預處理出前i個人的排隊總時間sum[i]&a…

wpf中xps文檔合并功能實現

原文:wpf中xps文檔合并功能實現跟著上一篇的xps文檔套打的文章&#xff0c;近期一直在研究xps打印技術&#xff0c;其中用戶提到了一個需求&#xff0c;要求能夠多頁面進行打印&#xff0c;我的想法是&#xff0c;先生成xps文件&#xff0c;然后將文件讀取出來以后&#xff0c;…

DCT(離散余弦變換(DiscreteCosineTransform))

離散余弦變換&#xff08;Discrete Cosine Transform&#xff0c;簡稱DCT變換&#xff09;是一種與傅立葉變換緊密相關的數學運算。在傅立葉級數展開式中&#xff0c;如果被展開的函數是實偶函數&#xff0c;那么其傅立葉級數中只包含余弦項&#xff0c;再將其離散化可導出余弦…