【问题标题】:WPF - MenuItem with children not firing bound commandWPF - 带有子项的 MenuItem 未触发绑定命令
【发布时间】:2013-10-24 04:49:53
【问题描述】:

所以我整天都在用这个把头撞在墙上。

在我的 WPF 应用程序(使用 MVVM Light)中,我有一个绑定到视图模型集合的上下文菜单,但它的行为并不完全正确。我可以创建我的菜单,并且一切都与我的 MenuItems 树的行为、正在执行的命令以及通过的正确参数完美配合。我正在使用它来制作允许用户将项目添加到文件夹的上下文菜单。

我遇到的问题是,当上下文菜单项有子项时,该命令不再被触发。因此,我只能将项目添加到没有子文件夹的文件夹中。

我使用 Snoop 对此进行了调查,我的 DataContext 正确显示为 MenuItem,并且命令绑定正确,并且 mousedown 事件确实被触发。

我遇到的问题是,如果 MenuItem 有子项,则它的命令不会被执行。任何没有子项的项目,命令都会毫无问题地执行。

我真的很茫然,Stack Overflow 或 MSDN social 上的所有类似问题都没有得到解答。

我已经设置了我的绑定样式。

<utility:DataContextSpy x:Key="Spy" />

<!-- Context style (in UserControl.Resources) -->

<Style x:Key="ContextMenuItemStyle" TargetType="{x:Type MenuItem}">
    <Setter Property="Header" Value="{Binding Header}"/>
    <Setter Property="ItemsSource" Value="{Binding Children}"/>
    <Setter Property="Command" Value="{Binding Command}" />
    <Setter Property="CommandParameter" Value="{Binding DataContext, Source={StaticResource Spy}" />
    <Setter Property="CommandTarget" Value="{Binding Path=PlacementTarget, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
</Style>

<!-- Later in the control -->
<ContextMenu ItemContainerStyle="{StaticResource ContextMenuItemStyle}" ItemsSource="{Binding MenuItems}" />

请注意,DataSpy 来自这篇文章,并且按照描述的方式工作,允许我将 usedcontrol 的数据上下文用作命令参数

http://www.codeproject.com/Articles/27432/Artificial-Inheritance-Contexts-in-WPF

这是用于上下文菜单的视图模型

public interface IContextMenuItem
{
    string Header { get; }
    IEnumerable<IContextMenuItem> Children { get; }
    ICommand Command { get; set; }
}

public class BasicContextMenuItem : ViewModelBase, IContextMenuItem
{
    #region Declarations

    private string _header;
    private IEnumerable<IContextMenuItem> _children;

    #endregion

    #region Constructor

    public BasicContextMenuItem(string header)
    {
        Header = header;
        Children = new List<IContextMenuItem>();
    }

    #endregion

    #region Observables

    public string Header
    {
        get { return _header; }
        set
        {
            _header = value;
            RaisePropertyChanged("Header");
        }
    }

    public IEnumerable<IContextMenuItem> Children
    {
        get { return _children; }
        set
        {
            _children = value;
            RaisePropertyChanged("Children");
        }
    }

    public ICommand Command { get; set; }

    #endregion
}

这是上下文项的实际使用方式。

MenuItems = new List<IContextMenuItem>
{
    new BasicContextMenuItem("New Folder") { Command = NewFolderCommand} ,
    new BasicContextMenuItem("Delete Folder") { Command = DeleteFolderCommand },
    new BasicContextMenuItem("Rename") { Command = RenameFolderCommand },
};

public ICommand NewFolderCommand
{
    get { return new RelayCommand<FolderViewModel>(NewFolder); }
}

private void NewFolder(FolderViewModel viewModel)
{
    // Do work
}

【问题讨论】:

  • 你是说当你点击 childmenuItem 时命令没有触发?
  • public ICommand Command { get; set; } 在哪里初始化?
  • @nit 我刚刚更新了问题,因为实际问题可能不太清楚。我遇到的问题是,如果 MenuItem 有孩子,它的命令不会被执行。任何没有子项的项目,命令都会毫无问题地执行。
  • @Bharath 我已更新问题以显示创建IContextMenuItem的示例

标签: c# wpf contextmenu mvvm-light menuitem


【解决方案1】:

我发现问题出在 XAML 绑定上。您需要的是HierarchicalDataTemplate 绑定。该代码没有为我认为导致问题的孩子绑定命令。

检查这是否有帮助 - Command binding not working in a dynamic MVVM Context Menu

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-13
    • 1970-01-01
    • 2017-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多