• WPF 入门笔记之事件


    一、事件路由

    1. 直接路由事件

      起源于一个元素,并且不能传递给其他元素

    MouserEnter 和MouserLeave 就是直接事件路由

    2. 冒泡路由事件

      在包含层次中向上传递,首先由引发的元素触发,然后被父元素引发,直到到达WPF的元素树的顶部位置

    例如:MouserUp

    以下控件都绑定了,MouseUp事件。根据输出的顺序表现冒泡路由的效果

    <Window x:Class="Haos.WPF.Case.Event.BubbleRouteWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:Haos.WPF.Case.Event"
            mc:Ignorable="d"
            Title="BubbleRouteWindow" Height="300" Width="300">
            <!--冒泡路由-->
        <Grid Margin="3" MouseUp="SomethingClick">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"></RowDefinition>
                <RowDefinition Height="*"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
            </Grid.RowDefinitions>
            <Label Margin="5" Background="AliceBlue" BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Center" Grid.Row="0" MouseUp="SomethingClick">
                <StackPanel MouseUp="SomethingClick">
                    <TextBlock Margin="3"  TextAlignment="Center" MouseUp="SomethingClick">Image and Picture Lable</TextBlock>
                    <Image Source="/Images/logo_ye.png" Width="20" Stretch="Fill" MouseUp="SomethingClick"></Image>
                    <TextBlock Margin="3" TextAlignment="Center" MouseUp="SomethingClick">Courtesy of the StackPanel</TextBlock>
                </StackPanel>
            </Label>
            <ListBox Margin="5" Name="lstMessage" Grid.Row="1"></ListBox>
            <CheckBox Margin="5" Grid.Row="2" Name="Check_Box">Handle first event</CheckBox>
            <Button Grid.Row="3" Margin="5" Padding="2" Click="Btn_Click">Clear List</Button>
        </Grid>
    </Window>
    namespace Haos.WPF.Case.Event
    {
        /// <summary>
        /// BubbleRouteWindow.xaml 的交互逻辑
        /// </summary>
        public partial class BubbleRouteWindow : Window
        {
            public BubbleRouteWindow()
            {
                InitializeComponent();
            }
    
            public int EventCounter = 0;
    
            /// <summary>
            /// MouseUp 的处理程序
            /// </summary>
            /// <param name="sender">触发者</param>
            /// <param name="e">事件参数</param>
            private void SomethingClick(object sender, MouseButtonEventArgs e)
            {
                EventCounter++;
                string message = $"#{EventCounter}:
    Sender:{sender.ToString()}
    Source:{e.Source}
    Original Source:{e.OriginalSource}";
                lstMessage.Items.Add(message);
                e.Handled = (bool)Check_Box.IsChecked;
            }
    
            private void Btn_Click(object sender, RoutedEventArgs e)
            {
                EventCounter = 0;
                lstMessage.Items.Clear();
            }
        }
    }

    3. 隧道路由事件

      在包含层次中向下传递,首先由WPF的元素树的顶部触发,然后向子元素引发,直到到达最后一个子元素

    隧道路由的事件名称以Preview开头,例如PreviewKeyDown键盘按下事件

    <Window x:Class="Haos.WPF.Case.Event.ChunnelRouteWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:Haos.WPF.Case.Event"
            mc:Ignorable="d"
            Title="ChunnelRouteWindow" Height="300" Width="300" PreviewKeyDown="SomethingKeyUp">
            <!--隧道路由事件-->
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"></RowDefinition>
                <RowDefinition Height="*"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
            </Grid.RowDefinitions>
            <StackPanel Grid.Row="0" PreviewKeyDown="SomethingKeyUp">
                <TextBlock Margin="3" HorizontalAlignment="Center" PreviewKeyDown="SomethingKeyUp">Image and text Lable</TextBlock>
                <Image Source="/Images/logo_ye.png" Width="20" Stretch="Fill" PreviewKeyDown="SomethingKeyUp"></Image>
                <DockPanel PreviewKeyDown="SomethingKeyUp">
                    <TextBlock PreviewKeyDown="SomethingKeyUp">Type here:</TextBlock>
                    <TextBox PreviewKeyDown="SomethingKeyUp"></TextBox>
                </DockPanel>
            </StackPanel>
            <ListBox Margin="5" Name="lstMessage" Grid.Row="1"></ListBox>
            <CheckBox Margin="5" Grid.Row="2" Name="Check_Box">Handle first event</CheckBox>
            <Button Grid.Row="3" Margin="5" Padding="2" Click="Btn_Click">Clear List</Button>
        </Grid>
    </Window>

    二、事件类型

    1. 生命周期事件

      1.1 Window.Initialized:在所有子元素都被设置完成时触发

        这个元素已经被构建出来,并且它的属性值都被设置好了,所以通常都是子元素先于父元素触发这个事件.当一个元素的 Initialized 事件被触发, 通常它的子树都已经初始化完成, 但是父元素还未初始化. 这个事件通常是在子树的 Xaml 被加载进来后触发的. 这个事件与 IsInitialized 属性相互绑定

      1.2 Window.Activated和Window.Deactivated:在窗口成为前台窗口时发生(激活)/在窗口成为后台窗口时发生

           户在运行系统上的多个窗口中切换时,Activated和Deactivated在窗口的生命周期里会发生多次

      1.3 Window.Loaded:在元素布局,呈现和准备交互时发生

        为了让一些事情能在所有内容都显示给用户之前马上执行,可以用Loaded事件

      1.4 Window.ContentRendered:在窗口的内容被渲染后发生

        ContentRendered事件只对窗口第一次完全呈现出来进行触发。为了让一些事情能在所有内容都显示给用户之后马上执行,可以用ContentRendered事件

      1.5 Window.Closed:当窗口即将关闭时发生  

      1.6 Window.Closing:Closed之后立即发生 Close 被调用,并且可以处理以取消关闭窗口。

    2.鼠标事件

    2.1 捕获鼠标坐标

    捕获鼠标相对,元素的位置

    2.2 捕获鼠标

    当元素捕获鼠标以后,其他元素就无法触发其他元素上的,鼠标按钮类事件。直到 Mouse.Capture(null);方法接受到一个null参数。

    2.3 鼠标拖放输入

     用户单击或选择元素上一块区域,拖放动作开始,将鼠标移动到其他的元素上并且该元素可以接受拖放信息。

     文本框自带拖放功能。

    首先设置鼠标按下事件时,绑定拖放的源。在放目标元素开启,允许放属性AllowDrop。同时绑定Drop事件处理放的操作

    <Window x:Class="Haos.WPF.Case.Event.MouseEventWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:Haos.WPF.Case.Event"
            mc:Ignorable="d"
            Title="MouseEventWindow" Height="300" Width="300">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
            </Grid.RowDefinitions>
            <!--获取鼠标位置-->
            <Rectangle Name="rect" Fill="AliceBlue" MouseMove="Rect_Move"></Rectangle>
            <!--捕获鼠标-->
            <Button Grid.Row="1" Name="Btn_Capture" Click="Capture_Click">Capture the Mouse</Button>
            <TextBlock Grid.Row="2" Name="Txt_Block">Mouse posstion at (0,0) in window coordinates</TextBlock>
            <DockPanel Grid.Row="3">
                <!--设置拖动的源-->
                <Label Background="DarkKhaki" Name="Txt_Scouce" MouseDown="Scouce_Down">this is label mouse</Label>
                <!--被放的对象,开启允许拖放接受数据 AllowDrop="True"-->
                <Label Background="Aqua" AllowDrop="True" Name="Lbl_Drop" Drop="Lbl_Drops"></Label>
            </DockPanel>
        </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 Haos.WPF.Case.Event
    {
        /// <summary>
        /// MouseEventWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MouseEventWindow : Window
        {
            public MouseEventWindow()
            {
                InitializeComponent();
            }
            /// <summary>
            /// 鼠标在矩形移动
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e">MouseEventArgs 不具备鼠标按钮,鼠标滚轮的事件提供的参数</param>
            private void Rect_Move(object sender, MouseEventArgs e)
            {
                //获取鼠标坐标
                Point point = e.GetPosition(this);
                Txt_Block.Text = $"Mouse posstion at ({point.X},{point.Y}) in window coordinates";
                if (point.X == 0)
                {
                    //让被捕获的鼠标释放
                    Mouse.Capture(null);
                }
            }
    
            private void Capture_Click(object sender, RoutedEventArgs e)
            {
                Mouse.Capture(rect);
                Btn_Capture.Content = "鼠标被捕获…";
            }
    
            /// <summary>
            /// 鼠标按下设置,拖放的源
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void Scouce_Down(object sender, MouseButtonEventArgs e)
            {
                Label lbl = sender as Label; ;
                //启动拖动
                DragDrop.DoDragDrop(lbl, lbl.Content, DragDropEffects.Copy);
            }
            /// <summary>
            /// 拖放,放的事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void Lbl_Drops(object sender, DragEventArgs e)
            {
                Label lbl = sender as Label;
                lbl.Content = e.Data.GetData(DataFormats.Text);
            }
        }
    }

    3.键盘事件

      按照执行顺序排列如下

      3.1 PreviewKeyDown:隧道键盘按下

      3.2 KeyDown:冒泡键盘按下

      3.3 PreviewTextInput:文本正在输入事件

      3.4 TextChanged:本文框值发生改变

      3.5 PreviewKeyUp:隧道键盘弹起

      3.6 KeyUp:冒泡键盘弹起

    <Window x:Class="Haos.WPF.Case.Event.KeyboardEventWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:Haos.WPF.Case.Event"
            mc:Ignorable="d"
            Title="KeyboardEventWindow" Height="300" Width="300">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"></RowDefinition>
                <RowDefinition Height="*"></RowDefinition>
                <RowDefinition Height="Auto"></RowDefinition>
            </Grid.RowDefinitions>
            <DockPanel Margin="5" Grid.Row="0">
                <TextBlock Margin="3">Type here:</TextBlock>
                <TextBox Focusable="True" PreviewKeyDown="KeyEvent" KeyDown="KeyEvent" PreviewKeyUp="KeyEvent" KeyUp="KeyEvent" PreviewTextInput="TextBox_PreviewTextInput" TextChanged="TextBox_TextChanged"></TextBox>
            </DockPanel>
            <ListBox Margin="5" Grid.Row="1" Name="lstMessage"></ListBox>
            <Button Grid.Row="2" Name="Btn_Clear" Padding="3" Margin="3" Click="Btn_Clear_Click">Clear ListBox</Button>
        </Grid>
    </Window>
    namespace Haos.WPF.Case.Event
    {
        /// <summary>
        /// KeyboardEventWindow.xaml 的交互逻辑
        /// </summary>
        public partial class KeyboardEventWindow : Window
        {
            public KeyboardEventWindow()
            {
                InitializeComponent();
            }
            
            private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
            {
                string message = $"Event:{e.RoutedEvent} Key:{e.Text}";
                lstMessage.Items.Add(message);
            }
    
            private void KeyEvent(object sender, KeyEventArgs e)
            {
                string message = $"Event:{e.RoutedEvent} Key:{e.Key}";
                lstMessage.Items.Add(message);
            }
    
            private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
            {
                string message = $"Event:{e.RoutedEvent}";
                lstMessage.Items.Add(message);
            }
    
            private void Btn_Clear_Click(object sender, RoutedEventArgs e)
            {
                lstMessage.Items.Clear();
            }
        }
    }

      3.7 焦点相关:

        Focusable设置控件是否能够获得焦点,和TabIndex属性设置按下Tab键获得焦点的顺序。在WPF中是使用树形结构布局的,所以当按下Tab键时,焦点会移动到当前元素的一个子元素。如果没有子元素,会移动到同级下一个元素的第一个子元素

    4.手写笔事件

    5.多点触控事件

  • 相关阅读:
    Git 获取远程分支
    entOS查看系统信息-CentOS查看命令
    CentOS6.5下用yum安装 git
    CENTOS如何禁用ROOT本地或远程SSH登录
    ProtoBuf练习(二)
    ProtoBuf练习(一)
    ProtoBuf练习
    Protocol Buffers官方文档(开发指南)
    Protocol Buffers官方文档(proto3语言指南)
    Boost Python学习笔记(五)
  • 原文地址:https://www.cnblogs.com/haosit/p/8953692.html
Copyright © 2020-2023  润新知