WPF事件的应用

        WPF中事件的类型有两种:①普通.NET事件 ②路由事件

        WPF事件一共有五类:①生命周期事件 ②鼠标事件 ③键盘事件 ④手写笔事件 ⑤触控事件

        这些事件支持着WPF程序的运作。

生命周期事件

        FrameworkElement类中定义的三个生命周期事件

                Initialized--普通.NET事件,元素实例化并设置了属性之后发生,即元素初始化完成。判断属性IsInitialized

                Loaded--样式应用和数据绑定的完成,元素呈现之前的最后一步发生。判断属性IsLoaded

                Unloaded--元素被释放时发生

                

                在Initialized之前,还存在ISupportInitialize接口的两个方法的执行:BeginInit()和EndInit()

        页面初始化和加载流程

                在最开始创建页面时,初始化行为是由内而外的,由子及父的,直至引发到最外层元素(例如窗口),即触发了最外层元素的Initialized事件,完成初始化过程。

                然后引发加载流程,加载行为是由外而内的,由父及子的,直至加载完所有元素,即触发了所有元素的Loaded事件,至此页面完整呈现。

        Window类的生命周期事件

 输入事件

                通过继承InputEventArgs的事件参数类传递额外的信息,InputEventArgs也是继承自RoutedEventArgs

                InputEventArgs的两个属性:Timestamp和Device

        键盘输入

                当按下键盘时,会发生一系列的事件,控件不同触发的事件也会不同。

                比如PreviewKeyDown->KeyDown->PreviewTextInput->TextInput->PreviewKeyUp->KeyUp

<TextBox TextInput="TextBox_TextInput" KeyDown="TextBox_KeyDown"/>	
        /// <summary>	
        /// 文本输入事件 TextInput	
        /// </summary>	
        /// <param name="sender"></param>	
        /// <param name="e"></param>	
        private void TextBox_TextInput(object sender, TextCompositionEventArgs e)	
        {	
            //TextInput事件从Text中获取控件即将接收到的文本	
            var txt = e.Text;	
            var eventObj = e.RoutedEvent;	
        }	
	
        /// <summary>	
        /// 键盘按键事件	
        /// </summary>	
        /// <param name="sender"></param>	
        /// <param name="e"></param>	
        private void TextBox_KeyDown(object sender, KeyEventArgs e)	
        {	
            //KeyDown / Up一类的事件都是从KeyEventArgs对象中,可以获取e.Key、e.IsRepeat,判断键入的Key值和是否重复。	
            var k = e.Key;	
            var r = e.IsRepeat;	
        }	

                根据实体键盘,可能会有同值但不同按键的情况,如Key.D7和Key.NumPad7,可以通过KeyConverter.ConverterToString()获得数字9

                在PreviewTextInput中e.Text接收不到某些按键(比如:空格键)的输入,需要使用PreviewKeyDown来补充处理。

        private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)	
        {	
            if (e.Key == Key.Space)	
            {	
                //禁止空格键输入,在此处拦截e.Handled = true; 空格输入不会进入PreviewTextInput	
                e.Handled = true;	
            }	
        }	
	
        private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)	
        {	
            Int16 val;	
            if (!Int16.TryParse(e.Text,out val))	
            {	
                //禁止非数字内容输入,在此处拦截e.Handled = true;	
                e.Handled = true;	
            }	
        }	

                按键事件可以关联到单个元素上,也可以关联到外层容器上,这样同时对容器内的元素生效的做法效率更高。

        焦点

                所有元素都可以被焦点选中,原因是Focusable属性是在UIElement类中定义的。

                控件类元素Focusable默认为True,非控件类元素Focusable默认为False。

                焦点的操作可通过鼠标点击、Tab键、方向键。

                Tab键移动顺序通常是从左向右、从上到下。

                Tab键移动顺序可以通过属性TabIndex和IsTabStop控制。

                不可见或禁用的控件会忽略Tab键焦点顺序。

        获取键盘状态

                可以检查Shift、Ctrl、Alt等修饰键的状态。

        private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)	
        {	
            bool a = e.KeyboardDevice.IsKeyToggled(Key.LeftCtrl);	
            bool b = e.KeyboardDevice.IsKeyDown (Key.LeftCtrl);	
            bool c = e.KeyboardDevice.IsKeyUp(Key.LeftCtrl);	
            KeyStates d = e.KeyboardDevice.GetKeyStates(Key.LeftCtrl);	
            bool f = Keyboard.IsKeyDown(Key.LeftCtrl);	
            bool g = Keyboard.IsKeyDown(Key.LeftCtrl);	
            bool h = Keyboard.IsKeyUp(Key.LeftCtrl);	
            KeyStates i = Keyboard.GetKeyStates(Key.LeftCtrl);	
        }	
        鼠标输入 

                MouseEnter(鼠标指针移动到元素上时引发)

                MouseLeave(鼠标指针离开元素上时引发)

                MouseEnter和MouseLeave是直接事件。

                PreviewMouseMove和MouseMove两个路由事件,当鼠标在元素上移动时引发。

        private void Rectangle_MouseMove(object sender, MouseEventArgs e)	
        {	
            //返回相对于指定元素的鼠标指针位置。	
            Point p = e.GetPosition(this);	
        }	

                鼠标命中测试的两个属性,源于UIElement类定义

                        IsMouseOver:确定当前鼠标是否位于某个元素及其子元素上面。注意:这里子元素即时超过父元素的边界依然可以捕捉到。

                        IsMouseDirectlyOver:检查鼠标是否直接位于某个元素上面。

        鼠标点击

                鼠标左/右键和滚轮操作的事件

PreviewMouseLeftButtonDownMouseLeftButtonDown
PreviewMouseLeftButtonUpMouseLeftButtonUp
PreviewMouseRightButtonDownMouseRightButtonDown
PreviewMouseRightButtonUpMouseRightButtonUp
PreviewMouseWheelMouseWheel

                MouseButtonEventArgs类继承自MouseEventArgs类

                这里面包含有属性MouseButton(获取引发事件的是哪个鼠标键)、ButtonBase(获取鼠标键的按下/释放状态)、ClickCount(鼠标键单击次数,区分单双击)

                通常鼠标单击是对Up事件的响应,而不是Down

                某些元素拥有更高级的鼠标事件,例如:Control类有PreviewMouseDoubleClick和MouseDoubleClick事件。

                与Keyboard静态对象类似,存在Mouse静态对象,可以用来判断鼠标的操作状态信息。

        捕获鼠标

                场景:鼠标在元素中按下并移动,移动至元素外释放,导致该元素无法接收到鼠标的释放事件。

                调用Mouse.Capture()并传递给目标元素以捕获鼠标。

                某个元素捕获鼠标后,其他元素就接收不到鼠标事件了。即鼠标被某个元素捕获后,就不能与其他元素进行交互了。

                应用场景:拖放改变元素尺寸、拖放等短时间的操作。

                

                Mouse.Capture(ccc,CaptureMode.SubTree);

                CaptureMode属性介绍

                        None:没有鼠标捕获。 鼠标输入转至鼠标下的元素。

                        Element:鼠标捕获应用于单个元素。 鼠标输入转至已捕获的元素。

                        SubTree:鼠标捕获应用于元素的子树。 如果鼠标悬停在具有捕获的元素的子级上,则会将鼠标输入发送至该子元素。 否则,会将鼠标输入发送至具有鼠标捕获的元素。

                鼠标捕获丢失可以使用元素的LostMouseCapture事件

        鼠标拖放

                System.Windows.DragDrop类,使任何元素都可以参与拖放操作。

<Window x:Class="Layout布局.拖放"
        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:Layout布局"
        mc:Ignorable="d"
        Title="拖放" Height="200" Width="500">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <TextBlock Grid.Column="0" Width="100" Background="AliceBlue" Text="你好" VerticalAlignment="Center" HorizontalAlignment="Center" x:Name="tb1" MouseDown="tb1_MouseDown"/>
        <!--接收拖放的元素要设置AllowDrop=True和Drop方法-->
        <TextBlock Grid.Column="1" Width="100" Background="AliceBlue" VerticalAlignment="Center" HorizontalAlignment="Center" x:Name="tb2" AllowDrop="True" Drop="tb2_Drop" DragEnter="tb2_DragEnter"/> 
    </Grid>
</Window>
 //通常在MouseDown或PreviewMouseDown时,进行DoDragDrop()操作
 private void tb1_MouseDown(object sender, MouseButtonEventArgs e)
 {
     var tb =  sender as TextBlock;
     DragDrop.DoDragDrop(tb,tb.Text,DragDropEffects.Move);
 }

 //目标元素 Drop放置
 private void tb2_Drop(object sender, DragEventArgs e)
 {
     var tb = sender as TextBlock;
     tb.Text = e.Data.GetData(DataFormats.Text).ToString();
 }

 //检查正在拖动的内容的数据类型
 private void tb2_DragEnter(object sender, DragEventArgs e)
 {
     if (e.Data.GetDataPresent(DataFormats.Text))
     {
         e.Effects = DragDropEffects.Copy;
     }
     else
     {
         e.Effects = DragDropEffects.None;
     }
 }

                 拖放操作的内容应当使用基本数据类型(字符串、数字等)以及实现了ISerializable或IDataObject的对象(可转换成字节流传递并重新构造成对象)。

        触控

                也有很多像鼠标和键盘输入一样的事件,如TouchDown、TouchUp等,还需要考虑旋转、多点触控、惯性等问题。

                这个地方不多说,特殊需要的时候再研究,多数时候用不到。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值