使用Observable Collection将命令数据绑定到Context Menu

时间:2014-07-21 22:34:18

标签: wpf xaml mvvm data-binding mvvm-light

我有一个带有一些选项的上下文菜单。其中一个选项是Observable集合,我遇到了将我的视图模型中的命令绑定到它们的问题。我已经看到了许多不同的方法来解决这个问题,但没有一个方法有效,因为它们与我的问题无关。这是我的代码:

XAML:

 <ListView ItemsSource="{Binding ListViewItems}" SelectionMode="Single">
            <ListView.ContextMenu>
                <ContextMenu DataContext="{Binding Path=PlacementTarget, RelativeSource={RelativeSource Self}}">
                    <MenuItem Header="Test" Command="{Binding TestCommand}" CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.SelectedItem}" />
                    <Separator></Separator>
                    <MenuItem Header="Status" ItemsSource="{Binding DataContext.ObservableCollectionList}" DisplayMemberPath="Name" Command="{Binding Path=DataContext.UpdateCommand}" CommandParameter="{Binding Path=SelectedItem}"/>
                </ContextMenu>
            </ListView.ContextMenu>
//listviewstuff here
</ListView>

VM:

public class VM : ViewModelBase
{
    public RelayCommand UpdateCommand { get; private set; }
    public Action UpdateCommandAction { get; set; }
    public ObservableCollection<Status> ObservableCollectionList { get; set; }

    public VM()
    {
        this.UpdateCommand = new RelayCommand(new Action(() => this.UpdateCommandAction.DynamicInvoke())));
    }
}

XAML视图的代码隐藏:

public partial class View
{
    public View()
    {
        InitializeComponent();
        var ViewDataContext = this.DataContext as VM;
        ViewDataContext .UpdateCommandAction = UpdateStatus;
    }


    private void UpdateStatus()
    {
        MessageBox.Show("test");
    }

}

我插入了一个断点,它甚至没有进入方法调用。我运行程序时,调试输出没有显示错误。我不明白的是,当我将此命令添加到未由数据绑定列表填充的常规菜单项时,它可以正常工作。我会很高兴看到一双新鲜的眼睛,并了解它是如何工作的。

2 个答案:

答案 0 :(得分:1)

您需要将命令绑定到所有子项,现在将它绑定在父项上将忽略它,因为它具有子项(而不是打开子菜单)。

要将其绑定到您需要ItemContainerStyle的孩子身上,请在那里为Setter创建Command。您需要再次走,可能是:{Binding DataContext.DataContext.UpdateCommand, RelativeSource={RelativeSource AncestorType=MenuItem}}(不确定AncestorLevel,如果它确实选择了自己而不是父项增加它;加倍DataContext因为你绑定到DataContext.ObservableCollectionList {1}},假设绑定实际工作)。

同样,菜单中没有SelectedItemSetter还需要另一个CommandParameter,它只会绑定到当前项目,即{Binding}


修改:代码示例:

<MenuItem Header="Status"
          ItemsSource="{Binding DataContext.ObservableCollectionList}"
          DisplayMemberPath="Name">
  <MenuItem.ItemContainerStyle>
    <Style TargetType="MenuItem">
      <Setter Property="Command" Value="{Binding DataContext.DataContext.UpdateCommand,
                                             RelativeSource={RelativeSource AncestorType=MenuItem}}"/>
      <Setter Property="CommandParameter" Value="{Binding}"/>
    </Style>
  </MenuItem.ItemContainerStyle>
</MenuItem>

答案 1 :(得分:0)

您需要List<MenuItem> MenuItems与ContextMenu ItemSource属性绑定为

public class MenuItem
{
    public string Header { get; set; }

    public ICommand Command { get; set; }
}

XAML:并设置itemContainerstyle

<ContextMenu ItemsSource="{Binding MenuItems}" >
        <ContextMenu.ItemContainerStyle>
            <Style TargetType="{x:Type MenuItem}" >
                <Setter Property="Header" Value="{Binding Header}"/>
                <Setter Property="Command" Value="{Binding Command}" />
            </Style>
        </ContextMenu.ItemContainerStyle>
    </ContextMenu>

并根据您的想法在ViewModel中添加所需的上下文菜单项。