为什么事件在 WPF/MVVM 应用程序中不触发
本文关键字:应用程序 MVVM 事件 WPF 为什么 | 更新日期: 2023-09-27 17:55:43
>我有以下导航栏,Content
数据模板标记如下:
<dxn:NavBarControl Name="SideMenuNavBar" DataContext="{Binding}" IsEnabled="{Binding Enabled}" ItemsSource="{Binding Bars}" HorizontalAlignment="Left" VerticalAlignment="Stretch" Margin="1">
<dxn:NavBarControl.Resources>
<Style TargetType="dxn:NavBarGroup">
<Setter Property="Header" Value="{Binding DisplayText}"/>
<Setter Property="Content" Value="{Binding MenuItems}"/>
<Setter Property="DisplaySource" Value="Content"/>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TreeView ItemsSource="{Binding}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Path=ChildItems}" DataType="{x:Type common:MenuItemBase}">
<TextBlock Text="{Binding ItemText}" HorizontalAlignment="Stretch">
<TextBlock.ContextMenu>
<ContextMenu DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}">
<MenuItem Header="{Binding MenuText}" Click="MenuItem_OnClick" />
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</dxn:NavBarControl.Resources>
<dxn:NavBarControl.View>
<dxn:NavigationPaneView GroupDisplayMode="Text" ItemDisplayMode="Text" MaxVisibleGroupCount="12"/>
</dxn:NavBarControl.View>
</dxn:NavBarControl>
绑定正在工作,因为我的一个菜单项树视图正确显示,但是当我单击(MouseDown
事件)时没有任何反应,或者当我双击以下处理程序时,处理程序不执行:
private void Control_OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
var x = sender;
}
我在var x = sender;
上的断点永远不会被命中。
注意:我知道我不应该使用事件,而应该使用命令或其他一些不太耦合的代码,但我迫切需要演示当用户单击菜单项时会发生什么,并且在事件之前,我的命令代码也没有触发。这里可能出了什么问题?
首先:ContextMenu
完全在您的控件之外VisualTree
因此正常的绑定将根本不起作用,除非您按照此处的说明更改绑定
由于您使用的是事件背后的代码,请尝试以下操作:
<MenuItem Header="{Binding MenuText}" MouseDown="MenuItem_MouseDown" />
和
private void MenuItem_MouseDown(object sender, MouseButtonEventArgs e)
{
var x = sender;
}
您应该使用命令绑定,确保绑定到创建命令的同一上下文。
如果<MenuItem Header="{Binding MenuText}" ...>
绑定正确,则应在同一上下文中创建中继命令。 然后通过以下方式绑定到点击
<MenuItem Click="{Binding ClickCommand}" ...?
但是,如果您需要快速修复,则可以在导航栏控件中使用PreviewMouseButtonDown/Up,然后检查处理程序中单击了什么?
请参阅:获取我clicked
/mousedown
的元素的名称
<dxn:NavBarControl PreviewMouseUp="NavBar_PreviewMouseUp" ...>
并在后面的代码中。
private void NavBar_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
var mouseWasUpOn = e.Source as MenuItem;
if (mouseWasUpOn != null)
{
string header = mouseWasDownOn.Header;
}
}
但请注意,如果正常的事件处理程序不起作用,这只是一种解决方法。理想情况下,您应该绑定到命令!
我对 WPF 很陌生,对 DevExpress WPF 套件也很陌生,所以我只是从某处的示例中复制了上面的原始代码。然后我心想,为什么要ContextMenu
?然后,我右键单击菜单项,出现一个空白的上下文菜单项,并触发了事件。我删除了血腥的上下文菜单,现在我的菜单项正在触发事件,就像我问这个问题时想要的那样。TreeView
的新结构如下:
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Path=ChildItems}" DataType="{x:Type menus:MenuItemBase}">
<MenuItem DataContext="{Binding}" Header="{Binding ItemText}" Click="MenuItem_OnClick" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
我仍在尝试使正确的命令绑定正常工作,但这回答了我关于事件的问题。