温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

WPF继续响应被标记为已处理事件的方法步骤

发布时间:2021-10-18 14:47:25 来源:亿速云 阅读:112 作者:iii 栏目:web开发

本篇内容介绍了“WPF继续响应被标记为已处理事件的方法步骤”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

WPF中在冒泡事件或者隧道事件会随其层间关系在visual tree上层层传递,但是,某些事件传递到某些控件是即会”终止“(不再响应相应的注册事件),给人一种事件终结者的印象。例如:textbox对mousdown事件。

产生原因:事件处理到达该控件后,其事件对象属性Handled被标记为True。WPF事件引擎在处理控件对应事件时,若检测到该属性为True,就不会调用相应的处理程序。即 WPF路由事件被标记为handled以后, 并不是不在visual tree上传递了;而是,事件引擎不再去调用这个事件的handler了。

若仍想再其上层元素中(上层是相对事件的传递方向而言)仍然处理响应的事件,解决方式:

1、若上层控件可以注册相应事件。即没有重写对应控件的Template属性。直接上代码:

<Grid MouseDown="Grid_MouseDown" >          <TextBox Name="txt1" Text="{Binding Path=txt1 ,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" MouseDown="Txt_MouseDown" />                    </Grid>
private void txt_MouseDown(object sender, MouseEventArgs e)   {      MessageBox.Show("TextMouseDown事件");      e.Handled = false;//使冒泡继续上传   }  private void Grid_MouseDown(object sender, MouseEventArgs e)   {      MessageBox.Show("GridMouseDown事件");   }

2、当自定义控件模板时,绑定模版事件不起效,此时用上面的方法不再生效。例如:自定义列表控件模版样式

<UserControl x:Class="Test"               xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"               xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"                xmlns:d="http://schemas.microsoft.com/expression/blend/2008"                mc:Ignorable="d"                d:DesignHeight="290" d:DesignWidth="180">      <Grid  name="gridMain">                 <ItemsControl Focusable="False" Background="Transparent" ItemsSource="{Binding InfoModel, Mode=OneWay}">                          <ItemsControl.Template>                              <ControlTemplate TargetType="ItemsControl">                                  <Border x:Name="scrBorder">                                      <ScrollViewer x:Name="scrollViewer" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"                                                   Padding="{TemplateBinding Padding}" MouseLeftButtonDown="MouseLeftButtonDown">                                          <ItemsPresenter />                                      </ScrollViewer>                                  </Border>                              </ControlTemplate>                          </ItemsControl.Template>                                                  <ItemsControl.ItemTemplate>                              <DataTemplate>                                  <Grid>                                      <Grid.ColumnDefinitions>                                          <ColumnDefinition Width="*"/>                                          <ColumnDefinition Width="Auto"/>                                          <ColumnDefinition Width="Auto"/>                                      </Grid.ColumnDefinitions>                                      <TextBlock Text="{Binding Desc}" Grid.Column="0"/>                                      <TextBlock Text="{Binding Value}" Margin="0" Grid.Column="1"/>                                      <TextBlock Text="{Binding Unit}" Grid.Column="2" Margin="3,0,15,0"/>                                  </Grid>                              </DataTemplate>                          </ItemsControl.ItemTemplate>                          <ItemsControl.ItemsPanel>                              <ItemsPanelTemplate>                                  <StackPanel></StackPanel>                              </ItemsPanelTemplate>                          </ItemsControl.ItemsPanel>                          <ItemsControl.ItemContainerStyle>                              <Style>                                  <Setter Property="Control.Margin" Value="1"/>  </Style>                          </ItemsControl.ItemContainerStyle>                      </ItemsControl>                  </Grid>  </UserControl>

ScrollViewer在控件模版中,ScrollViewer的MouseButtonDown事件处理事件如下:断点设置会发现鼠标点击时并不会触发。

private void MouseLeftButtonDown(object sender, MouseButtonEventArgs e)    {       //e.Handled = false ;    }

解决办法:UIElement.AddHandler 方法:为指定的路由事件添加路由事件处理程序,并将该处理程序添加到当前元素的处理程序集合中。具体解释详见:https://docs.microsoft.com/zh-cn/dotnet/api/system.windows.uielement.addhandler?f1url=https%3A%2F%2Fmsdn.microsoft.com%2Fquery%2Fdev15.query%3FappId%3DDev15IDEF1%26l%3DZH-CN%26k%3Dk(System.Windows.UIElement.AddHandler);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.5);k(DevLang-csharp)%26rd%3Dtrue&view=netframework-4.8

大体意思:由于WPF事件visual tree上传递过程中,某个元素将该事件标记为已处理,导致事件在传递时不再继续有响应,(原因:Handled被标记为True)如果希望后续元素也能响应此方法,可以使用此方法。

因此我们可以在上面UserControl的构造函数中添加下面代码:表示gridMain处理相应鼠标点击事件

public UserControl()         {              InitializeComponent();              gridMain.AddHandler(MouseLeftButtonDownEvent, new MouseButtonEventHandler(MouseLeftButtonDown), true);        }

再次断点调试MouseLeftButtonDown,会发现断点命中。

AddHandler这个代码的关键点是最后那个true,它告诉WPF引擎相应元素call这个handle,即使它被标记为Handled=true。但是元素处理后其上层元素也照样不会相应,因为handle仍被标记已处理。由此可见,WPF路由事件被标记为handled以后,并不是不在visual tree上传递了;而是,不去call这个handler了。

上例中如果想要UserControl继续响应,处境就与1一样了,只需将handle标记为false即可。

“WPF继续响应被标记为已处理事件的方法步骤”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

wpf
AI