为什么事件不在WPF / MVVM应用程序中触发?

时间:2014-04-01 13:34:37

标签: c# wpf mvvm devexpress prism-4

我有以下NavBar,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;上的断点永远不会被击中。

注意:我知道我不应该使用事件而是使用命令,或者其他更少耦合的代码,但是我迫切需要演示当用户单击菜单项时会发生什么,并且在事件发生之前,我的代码是命令也没有开火。这可能有什么问题?

3 个答案:

答案 0 :(得分:2)

首先:ContextMenu完全不在你的控件VisualTree之外,所以正常的绑定根本不会起作用,除非你按照描述更改你的绑定here

由于您使用的是Behind Event代码,请尝试以下操作:

<MenuItem Header="{Binding MenuText}" MouseDown="MenuItem_MouseDown" />

private void MenuItem_MouseDown(object sender, MouseButtonEventArgs e)
{
  var x = sender;
}

答案 1 :(得分:1)

您应该命令绑定,确保绑定到创建命令的相同上下文。

如果<MenuItem Header="{Binding MenuText}" ...>绑定正确,则应在同一上下文中创建RelayCommand。然后通过

绑定到点击

<MenuItem Click="{Binding ClickCommand}" ...?

但是如果你需要一个quickfix,你可以在你的NavBarControl中使用PreviewMouseButtonDown / Up,然后检查处理程序中的点击是什么?

请参阅:get the name of the element on which I 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;
    }
}

但请注意,如果普通事件处理程序不起作用,这只是一种解决方法。理想情况下,您应该绑定到Command!

答案 2 :(得分:0)

我对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>

我仍然试图让正确的命令绑定工作,但这回答了我关于这些事件的问题。