路由事件、鼠标键盘输入

 路由事件

路由事件使用以下三种路由策略之一:

  • 浮升(冒泡): 调用事件源上的事件处理程序。 路由事件随后会路由到后续的父级元素,直到到达元素树的根。 大多数路由事件都使用浮升路由策略。 浮升路由事件通常用于报告来自不同控件或其他 UI 元素的输入或状态变化。

  • 直接: 只有源元素本身才有机会调用处理程序以进行响应。 这类似于窗体用于事件的Windows路由"。 但是,与标准 CLR 事件不同,直接路由事件支持类处理 (类处理在即将发布的) 节中进行了说明,并且 和 可以使用 EventSetter EventTrigger 。

  • 隧道: 最初将调用元素树的根处的事件处理程序。 随后,路由事件将朝着路由事件的源节点元素(即引发路由事件的元素)方向,沿路由线路传播到后续的子元素。 合成控件的过程中通常会使用或处理隧道路由事件,通过这种方式,可以有意地禁止复合部件中的事件,或者将其替换为特定于整个控件的事件。 在 WPF 中提供的输入事件通常是以隧道/浮升对实现的。 隧道事件有时又称作预览事件,这是由该对所使用的命名约定决定的。

一般冒泡和隧道是成对出现的。隧道比较好认,会有Preview作为前缀。

例子: 

TunnelLabelClick

BubbledLabelClick

键盘输入:

焦点: Focusable  = true/false   空间元素默认为true,非控件默认false

控制焦点的顺序,TabIndex

<Window x:Class="Demo.WPFLearning.Keyboard"
        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:Demo.WPFLearning"
        mc:Ignorable="d"
        Title="Keyboard" Height="450" Width="400">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <DockPanel Margin="5">
            <TextBlock Margin="3"> Type Here</TextBlock>
            <TextBox Name="Textboxx" PreviewKeyDown="Textboxx_KeyEvent" KeyDown="Textboxx_KeyEvent" PreviewTextInput="Textboxx_TextInput"
                     PreviewKeyUp="Textboxx_KeyEvent" KeyUp="Textboxx_KeyEvent" TextChanged="Textboxx_TextChanged"></TextBox>
        </DockPanel>
        <ListBox Margin="5" Name="listMessage" Grid.Row="1"/>
        <Button Grid.Row="2" HorizontalAlignment="Right" Margin="5" Padding="3" Name="clear" Click="Clear_Click">Clear List</Button>
    </Grid>
</Window>
View Code
 public partial class Keyboard : Window
    {
        public Keyboard()
        {
            InitializeComponent();
        }
        public void Textboxx_KeyEvent(object sender,KeyEventArgs e)
        {
            string msg = "Event:" + e.RoutedEvent + "   Key:" + e.Key;
            this.listMessage.Items.Add(msg);
        }
        public void Textboxx_TextInput(object sender, TextCompositionEventArgs e)
        {
            string msg = "Event:" + e.RoutedEvent + "   Key:" + e.Text;
            this.listMessage.Items.Add(msg);
        }

        private void Textboxx_TextChanged(object sender, TextChangedEventArgs e)
        {
            string msg = "Event:" + e.RoutedEvent ;
            this.listMessage.Items.Add(msg);
        }

        private void Clear_Click(object sender, RoutedEventArgs e)
        {
            this.listMessage.Items.Clear();
        }
    }
View Code

鼠标输入:

移动事件 MousePosition:

MouseEventArgs对象 :包含标识鼠标状态的一些信息

直接事件:MouseEnter  、MouseLeave

隧道路由事件: PreviewMouseMove、MouseMove

    <Grid Margin="5">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Rectangle x:Name="rect" Fill="AliceBlue" MouseMove="Rect_MouseMove"/>
        <Button Grid.Row="1" Name="cmdCapture"> Capture the Mouse</Button>
        <TextBlock x:Name="Info" Grid.Row="2"/>
    </Grid>
View Code
        private void Rect_MouseMove(object sender, MouseEventArgs e)
        {
            Point pt = e.GetPosition(this);
            this.Info.Text = ("Mouse is at ( "+pt.X +" , "+pt.Y+" ) in window" );
        }
View Code

单击事件:

Mouse.Capture()进行捕获,第一个参数为鼠标,第二个参数为类型,可选

当一个鼠标事件被一个元素捕获后,其他元素就无法收到鼠标事件了,因此需要通知鼠标键释放事件(鼠标离开原来元素)

路由事件:

PreviewMouseLeftButtonDown、MouseRightButtonDown、LeftButtonDown、RightButtonDown

PreviewMouseLeftButtonUp、MouseRightButtonUp、LeftButtonUp、RightButtonUp

鼠标的拖放 MouseDragAndDrop

  1. 单击或者选择一些一些元素后,一些信息被搁置。
  2. 用户将鼠标移动到其他元素上,元素可以接受拖动的内容,鼠标指针变为拖放图标
  3. 释放鼠标键时 ,目标元素接收信息并对信息进行处理

 一些控件,如TextBox自带拖放的逻辑,对Lable写一些代码。

DragDrop.DoDragDrop(源, 属性内容, DragDropEffects.Copy(方式));

接收内容的元素 ,属性 AllowDrop 要修改为 true

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <TextBox Padding="10" VerticalAlignment="Center" HorizontalAlignment="Center" Text="Drag from this TextBox"/>
        <TextBox Padding="10" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Column="1"/>
        <Label x:Name="LabFrom"  Padding="20" VerticalAlignment="Center" HorizontalAlignment="Center" 
               Grid.Row="1" Background="#FFC4F1A3" MouseDown="LabFrom_MouseDown">or this Label</Label>
        <Label x:Name="LabTo"  Padding="20" VerticalAlignment="Center" HorizontalAlignment="Center" 
               Grid.Column="1" Grid.Row="1"  Background="#FFC4F1A3" AllowDrop="True" Drop="LabTo_Drop">To this Label</Label>

    </Grid>
View Code
 private void LabFrom_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Label label = (Label)sender;
            DragDrop.DoDragDrop(label,Content,DragDropEffects.Copy);
        }

        private void LabTo_Drop(object sender, DragEventArgs e)
        {
            Label label = (Label)sender;
            label.Content = e.Data.GetData(DataFormats.Text);
        }
View Code
原文地址:https://www.cnblogs.com/codinghard/p/15636569.html