C#?wpf利用附加屬性實(shí)現(xiàn)任意控件拖動(dòng)
前言
前面幾章講了控件拖動(dòng)的幾種方法,根據(jù)不同的布局可以有不同的拖動(dòng)方式。本章主要講的是利用附加屬性對(duì)幾種拖動(dòng)方式進(jìn)行封裝,實(shí)現(xiàn)復(fù)用性,否則直接注冊(cè)事件的方式在同界面多個(gè)控件中是幾乎沒(méi)有復(fù)用性的,實(shí)現(xiàn)起來(lái)很不方便。通過(guò)將上述幾章的所有功能整合到附加屬性中,增加靈活度和適用性。
一、如何實(shí)現(xiàn)
1.定義附加屬性
定義2個(gè)附加屬性,IsDragMoveable和DragMoveTarget,這兩個(gè)屬性沒(méi)有關(guān)系是分開(kāi)使用的。IsDragMoveable用來(lái)標(biāo)識(shí)一個(gè)控件自身是否可以拖動(dòng)。DragMoveTarget用于指明以本控件為拖動(dòng)點(diǎn),需要拖動(dòng)的控件(比如點(diǎn)擊標(biāo)題欄可以拖動(dòng)窗口,點(diǎn)擊窗口其他地方并不會(huì)拖動(dòng))。
IsDragMoveable:
public static bool GetIsDragMoveable(DependencyObject obj)
{
return (bool)obj.GetValue(IsDragMoveableProperty);
}
public static void SetIsDragMoveable(DependencyObject obj, bool value)
{
obj.SetValue(IsDragMoveableProperty, value);
}
/// <summary>
/// 控件是否能拖動(dòng)
/// </summary>
// Using a DependencyProperty as the backing store for IsDragMoveable. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsDragMoveableProperty =
DependencyProperty.RegisterAttached("IsDragMoveable", typeof(bool), typeof(Move), new PropertyMetadata(false));
DragMoveTarget:
public static Control GetDragMoveTarget(DependencyObject obj)
{
return (Control)obj.GetValue(DragMoveTargetProperty);
}
public static void SetDragMoveTarget(DependencyObject obj, Control value)
{
obj.SetValue(DragMoveTargetProperty, value);
}
/// <summary>
/// 拖動(dòng)目標(biāo),以本控件為拖動(dòng)點(diǎn),需要拖動(dòng)的目標(biāo)。使用場(chǎng)景比如標(biāo)題欄拖動(dòng)的是整個(gè)窗口
/// </summary>
// Using a DependencyProperty as the backing store for DragMoveTarget. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DragMoveTargetProperty =
DependencyProperty.RegisterAttached("DragMoveTarget", typeof(Control), typeof(Move), new PropertyMetadata(null));
2.整合功能
系列文章中的前四章節(jié)都是講述wpf的各種控件拖動(dòng)方法,都使用了相同3個(gè)鼠標(biāo)事件,所以將它們整合到一起還是比較容易的。具體代碼可參考前面四章的內(nèi)容。
整合的方法有很多種比如使用Switch的方式:
private void MouseDown(object sender, MouseButtonEventArgs e)
{
switch (moveType)
case MoveType.Grid://Grid內(nèi)控件鼠標(biāo)按下邏輯,參考《C# wpf 實(shí)現(xiàn)Grid內(nèi)控件拖動(dòng)》
break;
case MoveType.Canvas://Canvas內(nèi)控件鼠標(biāo)按下邏輯,參考《C# wpf 實(shí)現(xiàn)Canvas內(nèi)控件拖動(dòng))
break;
case MoveType.Window://Window鼠標(biāo)按下邏輯,參考《c# wpf 實(shí)現(xiàn)窗口任意區(qū)域點(diǎn)擊拖動(dòng))
break;
case MoveType.Others://其他控件鼠標(biāo)按下邏輯,參考《C# wpf 實(shí)現(xiàn)任意控件拖動(dòng)》
break;
}
}
private void MouseMove(object sender, MouseEventArgs e)
{
// 類似上面switch,略
}
private void MouseUp(object sender, MouseEventArgs e)
{
//類似上面switch,略
}3.關(guān)聯(lián)功能
在附加屬性的改變事件中關(guān)聯(lián)拖動(dòng)代碼,判斷不同的控件并注冊(cè)事件。
public void PropertyChangedCallback(Dependency0bject d, DependencyPropertyChangedEventArgs e)
{
// 1.判斷控件類型
// 2.注冊(cè)3個(gè)鼠標(biāo)事件
}二、使用示例
1.拖動(dòng)控件
(1)、Grid內(nèi)控件拖動(dòng)
代碼:
<Grid>
<Button local:CommonTools.IsDragMoveable="True" Width="120" Height="50" Content="移動(dòng)"/>
</Grid>
(2)、Canvas內(nèi)控件拖動(dòng)
<Canvas>
<Button local:CommonTools.IsDragMoveable="True" Width="120" Height="50" Content="移動(dòng)"/>
</Canvas>
(3)、其他任意控件拖動(dòng)
<StackPanel>
<Button local:CommonTools.IsDragMoveable="True" Width="120" Height="50" Content="移動(dòng)"/>
</StackPanel>
效果預(yù)覽,上面3中情況預(yù)覽效果是一樣的。
2.拖動(dòng)窗口
(1)通過(guò)按鈕拖動(dòng)窗口
標(biāo)簽其他無(wú)相關(guān)屬性略
<Window Name="window" >
<Grid>
<Button local:CommonTools.DragMoveTarget="{Binding ElementName=window}" Width="120" Height="50" Content="拖動(dòng)窗口" ></Button>
</Grid>
</Window>
效果預(yù)覽:

(2)整個(gè)窗口拖動(dòng)
標(biāo)簽其他無(wú)相關(guān)屬性略
<Window local:CommonTools.IsDragMoveable="True">
效果預(yù)覽1:

總結(jié)
總得來(lái)說(shuō)將拖動(dòng)功能封裝成一共附加屬性是很有用的。首先是具有通用性,在不同的窗口以及不同的項(xiàng)目中都可以使用,同時(shí)也減少了代碼維護(hù)量,修改時(shí)只需要集中改一出即可,然后使用方法也是比較簡(jiǎn)單直接。
到此這篇關(guān)于C# wpf利用附加屬性實(shí)現(xiàn)任意控件拖動(dòng)的文章就介紹到這了,更多相關(guān)C# wpf控件拖動(dòng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#實(shí)現(xiàn)根據(jù)數(shù)字序號(hào)輸出星期幾的簡(jiǎn)單實(shí)例
這篇文章主要介紹了C#實(shí)現(xiàn)根據(jù)數(shù)字序號(hào)輸出星期幾的簡(jiǎn)單實(shí)例,代碼簡(jiǎn)潔實(shí)用,也有助于初學(xué)者更好的理解C#的switch和if語(yǔ)句的流程控制,需要的朋友可以參考下2014-07-07
C# datatable 不能通過(guò)已刪除的行訪問(wèn)該行的信息處理方法
采用datatable.Rows[i].Delete()刪除行后再訪問(wèn)該表時(shí)出現(xiàn)出現(xiàn)“不能通過(guò)已刪除的行訪問(wèn)該行的信息”的錯(cuò)誤2012-11-11
C#實(shí)現(xiàn)倒計(jì)時(shí)關(guān)閉提示框功能
最近小編接到一個(gè)功能需要實(shí)現(xiàn)一個(gè)提示框并且能自動(dòng)關(guān)閉的,看到這個(gè)需求真是懵了,四處搜集資料才搞定,接下來(lái)通過(guò)本文給大家分享C#實(shí)現(xiàn)倒計(jì)時(shí)關(guān)閉提示框功能,感興趣的朋友跟隨小編一起看看吧2019-07-07
C#網(wǎng)站生成靜態(tài)頁(yè)面的實(shí)例講解
今天小編就為大家分享一篇關(guān)于C#網(wǎng)站生成靜態(tài)頁(yè)面的實(shí)例講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-01-01
C#?實(shí)例解釋面向?qū)ο缶幊讨械膯我还δ茉瓌t(示例代碼)
本文我介紹了?SOLID?原則中的單一功能原則(single-responsibility?principle),并通過(guò)?C#?代碼示例簡(jiǎn)明地詮釋了它的含意和實(shí)現(xiàn),對(duì)C#?面向?qū)ο缶幊淘瓌t感興趣的朋友跟隨小編一起看看吧2022-02-02
C# WinForm實(shí)現(xiàn)自動(dòng)更新程序之客戶端的示例代碼
這篇文章主要為大家詳細(xì)介紹了利用C# WinForm實(shí)現(xiàn)自動(dòng)更新程序之客戶端的實(shí)現(xiàn)方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以嘗試一下2022-10-10

