路由事件的类型:具体参考https://www.cnblogs.com/jellochen/p/3475754.html
- Tunnel隧道方式:路由事件使用隧道策略,以便事件实例通过树向下路由(从根到源元素)。
- Bubble冒泡方式:路由事件使用冒泡策略,以便事件实例通过树向上路由(从事件元素到根)。
- Direct直接方式:路由事件不通过元素树路由,仅在源元素发生,与.net事件类似,但其支持其他路由事件功能
当用户按下一个键,就会触发一系列的事件,这里按顺序依次列出公共的事件:
- PreviewKeyDown事件:隧道事件,按下一个键触发
- KeyDown事件:冒泡事件,按下一个键触发
- PreviewTextInput事件:隧道事件,当按键完成并且元素正在接受文本输入时发生。对于一些像Ctrl、Shift等不会产生文本输入的键不会触发该事件
- TextInput事件:冒泡事件,当按键完成并且元素正在接受文本输入时发生。对于一些像Ctrl、Shift等不会产生文本输入的键不会触发该事件
- PreviewKeyUp事件:隧道事件,当释放一个键时发生
- KeyUp事件:冒泡事件,当释放一个键时发生
上面是一些公共的事件,不同控件可能还有一些自己特有的事件,为了不冲突,还会将上面的导致冲突的事件挂起。例如TextBox控件拥有TextChanged事件,而挂起了TextInpute事件(不会触发)。因此,建议用Preview开头的事件
一般按键都会触发Preview开头的事件,除了特殊按键,如空格键、方向键、Alt键等非输入键。
案例:通过PreviewTextInput判断输入是否合法,不合法则阻止输入
XAML代码:
<Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <DockPanel Grid.Row="0"> <TextBlock Text="请输入数字:" Margin="3"/> <TextBox PreviewTextInput="TextBox_PreviewTextInput" /> </DockPanel> <ListBox x:Name="listBox" Grid.Row="1" Margin="5"/> <Button x:Name="Clear" Content="清除" Grid.Row="2" HorizontalAlignment="Right" Margin="5" Padding="3" Click="Clear_Click"/> </Grid>
CS代码:
private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e) { string message = "Event:" + e.RoutedEvent + " " + "Text:" + e.Text; this.listBox.Items.Add(message); long num = 0; if (!long.TryParse(e.Text, out num)) { MessageBox.Show(e.Text + "键不是数字"); e.Handled = true; } } private void Clear_Click(object sender, RoutedEventArgs e) { this.listBox.Items.Clear(); }
关于TextBlock和Label的比较,参考https://www.cnblogs.com/candyzhmm/p/6937290.html