我的编程空间,编程开发者的网络收藏夹
学习永远不晚

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

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

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

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

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

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

下载Word文档到电脑,方便收藏和打印~

下载Word文档

编程热搜

目录