使用可观察集合将命令数据绑定到上下文菜单 [英] Databinding a command to Context Menu with an Observable Collection

查看:153
本文介绍了使用可观察集合将命令数据绑定到上下文菜单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个上下文菜单有一些选项。其中一个选项是可观察的集合,并且我在我的视图模型中绑定了我的命令。我已经看到许多不同的方法来解决这个问题,但没有一个工作,因为他们没有与我的问题有关。以下是我的代码:



XAML:

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

VM:

 code> public class VM:ViewModelBase 
{
public RelayCommand UpdateCommand {get;私人集合}
public Action UpdateCommandAction {get;组; }
public ObservableCollection< Status> ObservableCollectionList {get;组; }

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

XAML视图的代码隐藏:

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


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

}

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

解决方案

您需要将命令绑定到所有孩子的项目,现在你绑定在父母将忽略它,因为它有子项目(打开子菜单代替)。



要绑定到孩子你需要 ItemContainerStyle ,为 Command 创建一个 Setter 。您将需要再次走上去,可能是这样的: {Binding DataContext.DataContext.UpdateCommand,RelativeSource = {RelativeSource AncestorType = MenuItem}} (不确定 AncestorLevel ,如果它选择自己,而不是父增加它; double DataContext 因为你绑定到 DataContext。 ObservableCollectionList ,假设绑定实际工作)。



同样没有 SelectedItem 在菜单中,您需要 Setter for CommandParameter ,它将简单地绑定到当前项,即 {Binding}






编辑:例如:

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


I have a Context menu with some options. One of the options is an Observable collection and I am having issues binding my commands in my view model to them. I have seen many different ways to fix this issue, but none have worked because they do not specifically relate to my problem. Here is my code first:

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())));
    }
}

Code-behind for the XAML view:

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


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

}

I inserted a break point and it's not even making it to the method call. The debug output is not showing an error for me when I run the program either. What I don't understand is when I add this Command to the regular menu item that is NOT populated by a data bound list, it works fine. I would appreciate a fresh pair of eyes and some insight in to how this works.

解决方案

You need to bind the command to all the child items, now you bind it on the parent which will ignore it because it has child items (opens sub-menu instead).

To bind it on the children you need the ItemContainerStyle, create a Setter for the Command there. You will need to walk up again, probably this: {Binding DataContext.DataContext.UpdateCommand, RelativeSource={RelativeSource AncestorType=MenuItem}} (not sure about the AncestorLevel, if it does select itself instead of the parent increase it; double DataContext because you bound to DataContext.ObservableCollectionList, assuming that binding to actually work).

Likewise there is no SelectedItem in a menu, you need another Setter for CommandParameter, it will simply bind to the current item, i.e. {Binding}.


Edit: Code example:

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

这篇关于使用可观察集合将命令数据绑定到上下文菜单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆