1. 程式人生 > >WPF之路-鍵盤與滑鼠事件

WPF之路-鍵盤與滑鼠事件

鍵盤事件

事件型別分為以下幾個型別

  • 生命週期事件:在元素載入與解除安裝的時候發生
  • 滑鼠事件:滑鼠動作
  • 鍵盤事件:鍵盤動作
  • 手寫筆事件:適用於win7以上的系統
  • 多點觸控事件:一個手指或多個手指的觸控動作

鍵盤事件

鍵盤事件的執行順序:

PrevieKeyDown

KeyDown

PreviewTextInput

TextInput

PreviewKeyUp

KeyUp

下面以例項程式碼證實:

在TextBox中分別新增PreviewKeyDown/KeyDown/PreviewTextInput/PreviewKeyUp/KeyUp/TextChanged事件

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <!--將容器分為三行-->
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
        </Grid.RowDefinitions>

        <!--新增一個停靠容器-->
        <DockPanel Margin="5">
            
            <TextBlock  >請輸入文字:</TextBlock>

            <!--Focusable="True" TabIndex="0" 表示是否開啟焦點,和設定tab切換焦點的順序 -->

            <TextBox Name="txt_input"  
                     PreviewKeyDown="txt_input_KeyEnvent"  
                     KeyDown="txt_input_KeyEnvent" 
                     PreviewTextInput="txt_input_TextInput" 
                     PreviewKeyUp="txt_input_KeyEnvent" 
                     KeyUp="txt_input_KeyEnvent" 
                     TextChanged="txt_input_TextChanged"  >
            </TextBox>
            
        </DockPanel>
        
        <!--內容展示與內容清除-->
        <ListBox Name="list_box" Margin="5" Grid.Row="1"></ListBox>
        <Button Name="btn_clear" Content="清空內容" Grid.Row="2" Margin="5" Padding="3" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="Auto" Click="btn_clear_Click"/>
    </Grid>
</Window>

事件對應自帶程式程式碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.
Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WpfApp1 { /// <summary> /// MainWindow.xaml 的互動邏輯 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); }
//清空ListBox的內容 private void btn_clear_Click(object sender, RoutedEventArgs e) { this.list_box.Items.Clear(); } //文字框按下事件 private void txt_input_KeyEnvent(object sender, KeyEventArgs e) { string message = "事件:"+e.RoutedEvent+"-鍵:"+e.Key; this.list_box.Items.Add(message); } // 文字輸入事件 private void txt_input_TextInput(object sender, TextCompositionEventArgs e) { string message = "事件:" + e.RoutedEvent + "-值:" + e.Text; this.list_box.Items.Add(message); } private void txt_input_TextChanged(object sender, TextChangedEventArgs e) { string message = "事件:" + e.RoutedEvent ; this.list_box.Items.Add(message); } } }

執行程式,檢視結果:

在文字框中輸入"s",從ListBox中的輸出可以看出,先執行的是“按下事件”,然後是“文字輸入事件”,然後是“鍵的釋放事件”,對應的隧道事件總先於對應的冒泡事件

以上示例有助於理解隧道事件與冒泡事件、還有鍵盤事件

滑鼠事件

滑鼠單擊

捕獲滑鼠

滑鼠拖放

滑鼠事件有:

  • MouseEnter事件
  • MouseLeave事件,這兩個事件都是直接事件
  • PreviewMouseMove事件
  • MouseMove事件,這兩個會提供MouseEventArgs屬性

滑鼠移動事件MouseMove

在介面定義一個矩形,在該矩形上繫結滑鼠移動事件,將滑鼠的座標點裡時時的顯示在一個TextBox中,這樣,便能清晰的看出滑鼠移動事件的作用

<Window x:Class="WpfApp1.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="450" Width="800">
    <Grid Margin="5">
        <!--定義三行-->
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
        </Grid.RowDefinitions>

        <!--定義一個淺藍色的矩形,並繫結滑鼠移動事件-->
        <Rectangle Name="rect" Fill="LightBlue" MouseMove="Event_MouseMove"></Rectangle>
        <Button Grid.Row="1" Name="cmdCallpture">捕獲滑鼠</Button>
        <TextBlock Name="lblInfo" Grid.Row="2"></TextBlock>
    </Grid>
</Window>

滑鼠移動事件處理程式程式碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace WpfApp1
{
    /// <summary>
    /// Window1.xaml 的互動邏輯
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

		//滑鼠移動事件處理程式
        private void Event_MouseMove(object sender, MouseEventArgs e)
        {
            //GetPosition返回相對指定元素的滑鼠位置
            Point pt = e.GetPosition(this);
            //移動滑鼠的時候,將滑鼠的座標顯示出來
            this.lblInfo.Text = ("You are at ("+pt.X+","+pt.Y+") in window coordinates");
        }
    }
}

執行效果:

滑鼠的單擊事件

PreviewMouseLeftButtonDown

PreviewMouseRightButtonDown

MouseLeftButtonDown

MouseRightButtonDown

PreviewMouseLeftButtonUp

PreviewMouseRightButtonUp

MouseLeftButtonUp

MouseRightButtonUp

捕獲滑鼠

當滑鼠被捕獲以後,滑鼠便不能再點選容器的其它元素

<Window x:Class="WpfApp1.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="450" Width="800">
    <Grid Margin="5">
        <!--定義三行-->
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
        </Grid.RowDefinitions>

        <!--定義一個淺藍色的矩形,並繫結滑鼠移動事件-->
        <Rectangle Name="rect" Fill="LightBlue" MouseMove="Event_MouseMove"></Rectangle>
        <!--為按鈕繫結單擊事件,用來捕獲滑鼠-->
        <Button Grid.Row="1" Name="cmdCapture" Click="Event_Click">捕獲滑鼠</Button>
        <TextBlock Name="lblInfo" Grid.Row="2"></TextBlock>
    </Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace WpfApp1
{
    /// <summary>
    /// Window1.xaml 的互動邏輯
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private void Event_MouseMove(object sender, MouseEventArgs e)
        {
            //GetPosition返回相對指定元素的滑鼠位置
            Point pt = e.GetPosition(this);
            //移動滑鼠的時候,將滑鼠的座標顯示出來
            this.lblInfo.Text = ("You are at ("+pt.X+","+pt.Y+") in window coordinates");
        }

		//單擊事件處理程式 
        private void Event_Click(object sender, RoutedEventArgs e)
        {
            //Mouse.Capture()將滑鼠輸入捕獲到指定元素
            //當滑鼠被捕獲以後,滑鼠便無法再點選視窗上其他元素
            Mouse.Capture(this.rect);
            this.cmdCapture.Content = "滑鼠已經被捕獲";
        }
    }
}

如圖,當滑鼠被捕獲以後,點選視窗的最大化最小化都無法工作了

滑鼠拖動

滑鼠的拖動指將滑鼠從一個元素上按下滑鼠左鍵,然後拖動到另一個元素上,釋放滑鼠左鍵,從而將相應的內容移動到第二個元素上去

TextBox控制元件預設支援滑鼠拖動,請看示例:

<Window x:Class="WPF_CODE.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        
        <TextBox Name="txt_1" Grid.Column="0" Width="Auto" HorizontalAlignment="Center" VerticalAlignment="Center">TextBox Hello</TextBox>
        <!--AllowDrop屬性允許自身成為拖動源的目標-->
        <Label Name="lab_fir" AllowDrop="True" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" MouseDown="lab_fir_MouseDown">Lable First</Label>
        <Label Name="lab_sec" AllowDrop="True" Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Center" Drop="lab_sec_Drop">Lable Second</Label>
    
    </Grid>
</Window>

後端程式碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WPF_CODE
{
    /// <summary>
    /// MainWindow.xaml 的互動邏輯
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        //第一個lable,當滑鼠按下時,啟動拖動效果
        private void lab_fir_MouseDown(object sender, MouseButtonEventArgs e)
        {
            //獲取事件激發者,即第一個lable
            Label lb = (Label)sender;

            //DragDrop.DoDragDrop指啟動拖放操作
            //引數分別是啟動拖動的物件,要操作的型別,拖動型別
            DragDrop.DoDragDrop(lb, lb.Content, DragDropEffects.Move);
        }

        //第二個lable,當拖拽事件在它身上發生時
        private void lab_sec_Drop(object sender, DragEventArgs e)
        {
            //從DragEventArgs裡獲取到拖拽的內容進行載入
            ((Label)sender).Content = e.Data.GetData(DataFormats.Text);
        }
    }
}

效果是:

文字框的內容可以拖拽到第一個和第二個lable上

第一個lable的內容可以拖拽到文字框和第二個lable上

第二個lable可以拖拽到文字框上