亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

WPF中鼠標(biāo)/鍵盤/拖拽事件以及用行為封裝事件詳解

 更新時間:2023年03月02日 14:06:04   作者:步、步、為營  
這篇文章主要為大家詳細(xì)介紹了WPF中常用的鼠標(biāo)事件、鍵盤事件以及注意事項,同時使用一個案例講解了拓展事件,感興趣的小伙伴可以了解一下

本文主要介紹了WPF中常用的鼠標(biāo)事件、鍵盤事件以及注意事項,同時使用一個案例講解了拓展事件。除此之外,本文還講述如何用行為(Behavior)來封裝事件。

Windows中的事件通過消息機制來完成,也就是Windows系統(tǒng)來捕獲用戶輸入(如鼠標(biāo)點擊、鍵盤輸入),然后Windows發(fā)送一個消息給應(yīng)用程序,應(yīng)用程序進行具體的處理。在Winform中,窗體中每個控件都是有獨立的句柄,也就是每個控件都可以收到Windows系統(tǒng)傳來的消息,但是在WPF中,窗體中的控件是沒有句柄的,所以只能是窗體進行消息捕獲,WPF框架經(jīng)過處理再傳遞給相應(yīng)的控件。這是WPF和Winform在事件處理上的不同之處。

鼠標(biāo)事件

常用的鼠標(biāo)事件包括:

MouseEnter、MouseLeave、MouseDown、MouseUp、MouseMove、MouseLeftButtonDown、MouseLeftButtonUp、MouseRightButtonDown、MouseRightButtonUp、MouseDoubleClick

值得注意的是諸如Button一類的控件,具有Click事件,它其實是仍然是調(diào)用了MouseLeftButtonDown等底層事件,然后進行截斷,也就是說Button控件只能調(diào)用Click事件而不能調(diào)用MouseLeftButtonDown事件,因為在Click事件中,調(diào)用了MouseLeftButtonDown事件,而且應(yīng)用了e.Handled = true;阻止事件向下傳下去。如果要在Click事件之前進行事件處理,則可以使用PreviewMouseLeftButtonDown事件。

鍵盤輸入事件

用的最多的鍵盤輸入事件有:

KeyDown、KeyUp、TextInput

如果要對某個鍵進行處理則可以

private void TextBox_KeyDown(object sender, KeyEventArgs e)
{
    if(e.Key == Key.Enter)
    {
        //e.Handled = true;//表示已經(jīng)處理完成
        //具體邏輯
    }
}

注意TextBox是不能捕獲到TextInput事件的,只能捕獲到KeyDown、TextChanged等事件,但也可以捕獲到PreviewTextInput事件,事件捕獲順序是KeyDown-PreviewTextInput-TextChanged。

案例:做一個搜索欄,輸入文字后回車搜索

實現(xiàn)方式1:可以在TextBox上增加KeyDown事件,捕獲Key.Enter鍵。

實現(xiàn)方式2:增加一個Button按鈕,設(shè)置<Button Content="搜索" IsDefault="True"/>

拖拽事件

拖拽事件包括:Drop、DragLeave、DragOver、DragEnter事件

案例,將某個控件拖拽到另一個區(qū)域

界面XAML

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <StackPanel x:Name="panel"  Background="#F7F9FA">
        <Border Background="Orange" Height="30" Width="30" MouseLeftButtonDown="Border_MouseLeftButtonDown"/>
    </StackPanel>
    <!--必須設(shè)置Background,否則默認(rèn)為null,null是沒有背景和Transparent不同-->
    <!--AllowDrop="True"必須設(shè)置-->
    <Canvas x:Name="canvas" Grid.Column="1" Drop="Canvas_Drop" AllowDrop="True" 
            Background="Transparent">
    </Canvas>
</Grid>

實現(xiàn)代碼

private void Canvas_Drop(object sender, DragEventArgs e)
{
    var data = e.Data.GetData(typeof(Border));
    //canvas.Children.Add(data);//直接這樣不可以,因為同一個實例不允許在于兩個容器中
    //先在之前的容器中移除,再添加
    panel.Children.Remove(data as UIElement);
    canvas.Children.Add(data as UIElement);

    //獲得鼠標(biāo)相對于canvas的位置
    var point = e.GetPosition((Canvas)sender);
    Canvas.SetLeft(data as UIElement, point.X);
    Canvas.SetTop(data as UIElement, point.Y);
}

private void Border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    Border border = sender as Border;
    DragDrop.DoDragDrop(border, border, DragDropEffects.Copy);
}

用行為封裝事件

通過一個案例來講解

案例,實現(xiàn)某個控件的隨意拖動

用事件來實現(xiàn)

主要是通過MouseLeftButtonDown、MouseLeftButtonUp和MouseMove三個事件來實現(xiàn)

XAML界面

<Canvas>
    <Border Background="Orange" Width="100" Height="50" Canvas.Left="100" Canvas.Top="100"
            MouseLeftButtonDown="Border_MouseLeftButtonDown"
            MouseLeftButtonUp="Border_MouseLeftButtonUp"
            MouseMove="Border_MouseMove"
            />
</Canvas>

實現(xiàn)代碼

private Canvas _parentCanvas = null;
private bool _isDragging = false;
private Point _mouseCurrentPoint;
private void Border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    //獲得承載Border的父對象
    if (_parentCanvas == null)
        _parentCanvas = (Canvas)VisualTreeHelper.GetParent(sender as Border);

    this._isDragging = true;
    //獲得相對于border的坐標(biāo)
    this._mouseCurrentPoint = e.GetPosition(sender as Border);
    //關(guān)鍵,鎖定鼠標(biāo)即不讓鼠標(biāo)選中其他元素
    (sender as Border).CaptureMouse();
}

private void Border_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    if (_isDragging)
    {
        //關(guān)鍵,取消鎖定鼠標(biāo)
        (sender as Border).ReleaseMouseCapture();
        _isDragging = false;
    }
}

private void Border_MouseMove(object sender, MouseEventArgs e)
{
    if (_isDragging)
    {
        //獲得相對于Canvas的坐標(biāo)
        Point point = e.GetPosition(_parentCanvas);

        (sender as Border).SetValue(Canvas.TopProperty, point.Y - _mouseCurrentPoint.Y);
        (sender as Border).SetValue(Canvas.LeftProperty, point.X - _mouseCurrentPoint.X);
    }
}

關(guān)鍵點

在進行移動的時候,一定要鎖定鼠標(biāo),也就是不讓鼠標(biāo)可以選中其他元素,如果不鎖定會出現(xiàn)以下情況:

情況1:如果鼠標(biāo)移動過快,會出現(xiàn)圖形不能跟隨的情況

情況2:如果有多個元素,會出現(xiàn)選中其他元素的情況

下圖演示中,鼠標(biāo)箭頭未松開

鎖定鼠標(biāo)有兩種方式

(sender as Border).CaptureMouse()//鎖定
(sender as Border).ReleaseMouseCapture();//解鎖

System.Windows.Input.Mouse.Capture(sender as Border);//鎖定
System.Windows.Input.Mouse.Capture(null);//解鎖

用行為來封裝

上文中主要是通過MouseLeftButtonDown、MouseLeftButtonUp和MouseMove三個事件來實現(xiàn),在XAML中需要對這三個事件進行綁定。行為則可以將這三個事件封裝在一起。

  • 使用行為需要nuget安裝Microsoft.Xaml.Behaviors.Wpf,F(xiàn)rameWork版本安裝System.Windows.Interactivity.WPF
  • 新建一個類,繼承自Behavior<T>,類中重寫OnAttached()和OnDetaching()方法。

OnAttached()表示當(dāng)掛載到對應(yīng)的對象上的時候觸發(fā)

OnDetaching()在對象銷毀時觸發(fā)

public class DragMoveBehavior : Behavior<Border>
{
    // 當(dāng)掛載到對應(yīng)的對象上的時候觸發(fā)
    protected override void OnAttached()
    {
        base.OnAttached();
		//方法與上面相同
        //this.AssociatedObject表示關(guān)聯(lián)的對象
        this.AssociatedObject.MouseLeftButtonDown += AssociatedObject_MouseLeftButtonDown;
        this.AssociatedObject.MouseLeftButtonUp += AssociatedObject_MouseLeftButtonUp;
        this.AssociatedObject.MouseMove += AssociatedObject_MouseMove;
    }

    private Canvas _parentCanvas = null;
    private bool _isDragging = false;
    private Point _mouseCurrentPoint;
    private void AssociatedObject_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
    {
        if (_isDragging)
        {
            // 相對于Canvas的坐標(biāo)
            Point point = e.GetPosition(_parentCanvas);
            // 設(shè)置最新坐標(biāo)
            this.AssociatedObject.SetValue(Canvas.TopProperty, point.Y - _mouseCurrentPoint.Y);
            this.AssociatedObject.SetValue(Canvas.LeftProperty, point.X - _mouseCurrentPoint.X);
        }
    }

    private void AssociatedObject_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        if (_isDragging)
        {
            // 釋放鼠標(biāo)鎖定
            //this.AssociatedObject.ReleaseMouseCapture();
            System.Windows.Input.Mouse.Capture(null);
            _isDragging = false;
        }
    }

    private void AssociatedObject_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        this._isDragging = true;
        // Canvas
        if (_parentCanvas == null)
            _parentCanvas = (Canvas)VisualTreeHelper.GetParent(sender as Border);
        // 當(dāng)前鼠標(biāo)坐標(biāo)
        this._mouseCurrentPoint = e.GetPosition(sender as Border);
        // 鼠標(biāo)鎖定
        //this.AssociatedObject.CaptureMouse();
        System.Windows.Input.Mouse.Capture(this.AssociatedObject);
    }

    // 對象銷毀
    protected override void OnDetaching()
    {
        this.AssociatedObject.MouseLeftButtonDown -= AssociatedObject_MouseLeftButtonDown;
        this.AssociatedObject.MouseLeftButtonUp -= AssociatedObject_MouseLeftButtonUp;
        this.AssociatedObject.MouseMove -= AssociatedObject_MouseMove;
    }
}

XAML中代碼

<Canvas>
    <Border Background="Orange" Width="100" Height="50" Canvas.Left="100" Canvas.Top="100">
        <i:Interaction.Behaviors>
            <local:DragMoveBehavior/>
        </i:Interaction.Behaviors>
    </Border>
</Canvas>

以上就是WPF中鼠標(biāo)/鍵盤/拖拽事件以及用行為封裝事件詳解的詳細(xì)內(nèi)容,更多關(guān)于WPF事件的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C#通過域名獲得IP地址的方法

    C#通過域名獲得IP地址的方法

    這篇文章主要介紹了C#通過域名獲得IP地址的方法,涉及C#中GetHostByName方法的使用技巧,需要的朋友可以參考下
    2015-04-04
  • Unity實現(xiàn)答題系統(tǒng)的示例代碼

    Unity實現(xiàn)答題系統(tǒng)的示例代碼

    這篇文章主要和大家分享了利用Unity制作一個答題系統(tǒng)的示例代碼,文中的實現(xiàn)方法講解詳細(xì),對我們學(xué)習(xí)或工作有一定的幫助,需要的可以參考一下
    2022-05-05
  • C#使用IronPython庫調(diào)用Python腳本

    C#使用IronPython庫調(diào)用Python腳本

    這篇文章介紹了C#使用IronPython庫調(diào)用Python腳本的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • 關(guān)于C# TabPage如何隱藏的問題

    關(guān)于C# TabPage如何隱藏的問題

    TabPage沒有Visible屬性,所以只能通過設(shè)置將其與父控件(tabcontrol)的關(guān)聯(lián)性去除就好了,如下面代碼:
    2013-04-04
  • C#的正則表達式Regex類使用簡明教程

    C#的正則表達式Regex類使用簡明教程

    這篇文章主要介紹了C#的正則表達式Regex類使用簡明教程,分別講解了如何匹配、如何獲取匹配次數(shù)、如何獲取匹配內(nèi)容及捕獲的方法,需要的朋友可以參考下
    2014-08-08
  • Unity自定義編輯器界面(Inspector界面)

    Unity自定義編輯器界面(Inspector界面)

    這篇文章主要為大家詳細(xì)介紹了Unity自定義編輯器界面,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • C#中的數(shù)組作為參數(shù)傳遞所引發(fā)的問題

    C#中的數(shù)組作為參數(shù)傳遞所引發(fā)的問題

    這篇文章主要介紹了C#中的數(shù)組作為參數(shù)傳遞所引發(fā)的問題 的相關(guān)資料,需要的朋友可以參考下
    2016-03-03
  • C#控制臺下測試多線程的方法

    C#控制臺下測試多線程的方法

    這篇文章主要介紹了C#控制臺下測試多線程的方法,涉及C#操作多線程的技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-04-04
  • C# 泛型數(shù)組學(xué)習(xí)小結(jié)

    C# 泛型數(shù)組學(xué)習(xí)小結(jié)

    C# 泛型數(shù)組學(xué)習(xí)中我們需要注意什么事項呢?C# 泛型數(shù)組的使用又是如何呢?那么本文就向你詳細(xì)介紹這方面的內(nèi)容
    2012-09-09
  • c# 反射用法及效率對比

    c# 反射用法及效率對比

    這篇文章主要介紹了c# 反射用法及效率對比,幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下
    2021-02-02

最新評論