WPF带有上下文菜单的按钮

5

我是WPF的新手,正在尝试将上下文菜单绑定到一个按钮上,上下文菜单项来自于视图模型。

这是我的做法:

<Button x:Name="btn" Content="Context Menu">
  <Button.ContextMenu>
    <ContextMenu x:Name="cm" ItemsSource="ItemsList"/>
  </Button.ContextMenu>
</Button>

private List<string> itemsList = null;
public List<string> ItemsList
{
  get
  {
    if(itemsList == null)
      itemsList = new List<string>(myStringArrayOfItems);
    return itemsList;                
  }
}

XAML编辑器一直显示错误:TypeConverter for "IEnumerable"不支持从字符串进行转换。我在这里做错了什么?
另外,假设我让它工作了,我该怎么绑定这些项目到一个命令并在点击项目时执行一些操作?我想对所有菜单项运行相同的命令,只使用项目字符串作为参数。

请问对此有什么想法吗? - Padmaja
2个回答

10
如果您使用 ItemsSource="ItemsList",则不会将其绑定到 ItemsList,而是将其设置为字符串 ItemsList,因此会出现错误。请尝试按以下方式进行绑定:
<ContextMenu x:Name="cm" ItemsSource="{Binding Path=ItemsList}"/>

关于Command部分,您需要一些实现ICommand接口的代码(例如这里),然后像在ItemContainerStyle中绑定一样:

<ContextMenu ...>
   <ContextMenu.ItemContainerStyle>
      <Style TargetType="{x:Type MenuItem}">
         <Setter Property="Command" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}, Path=PlacemantTarget.DataContext.ItemChanged }"/>
         <Setter Property="CommandParameter" Value="{Binding}"/>
      </Style>
   </ContextMenu.ItemContainerStyle>
</ContextMenu >

谢谢dkozl。我现在可以获取数据了。但是由于某种原因,XAML一直说“Command”不是我可以设置的属性。我想我可能做了一些愚蠢的事情,但不确定是什么。 - Padmaja
尝试 <Style TargetType="{x:Type MenuItem}"> - dkozl
虽然现在没有抛出任何错误,但命令没有被触发。也许我们不应该在这里使用“ItemContainerStyle”? - Padmaja
这是绑定“Command”的地方。你绑定的命令在哪里定义?它是“ItemsList”类所定义的另一个属性吗? - dkozl
是的。我已将它作为一个ICommand属性存储在视图模型中,如下所示(我正在使用MVVM Light来处理RelayCommand):public ICommand ItemChanged { get; set; }//在构造函数中 ItemChanged = new RelayCommand(ChangeItem);public void ChangeItem() { MessageBox.Show("项目已更改"); } - Padmaja
所以你只需要改变上下文。目前每个项目的上下文是显示的字符串,你需要向上遍历可视树,其中上下文是列表/命令容器类。我已经更新了我的答案。现在它还应该将绑定的字符串值传递给命令调用。 - dkozl

2

xaml

<Button  Content="0k">
        <Button.ContextMenu>
            <ContextMenu x:Name="cm" ItemsSource="{Binding ItemsList}" />
        </Button.ContextMenu>
    </Button>

xaml.cs

public MainWindow()
    {
        InitializeComponent();
        DataContext = new MyViewModel();
    }

视图模型

    public class MyViewModel : INotifyPropertyChanged
{

    public MyViewModel()
    {
        ItemsList = new List<string> { "abc", "xyz" };
    }

    private List<string> itemsList = null;

    public List<string> ItemsList
    {
        get
        {
            return itemsList;
        }
        set
        {

            if (itemsList == null)
            {
                itemsList = value;
                Notify("ItemsList");
            }

        }
    }

    private void Notify(string propName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
    }

    public event PropertyChangedEventHandler PropertyChanged;

}

我希望这可以帮到你。


为什么我无法从xaml.cs按名称访问ContextMenu? - demo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接