2
votes

I'm attempting to follow this answer on how to make an MVVM context menu in WPF. It sounds easy enough: "The ItemTemplate for the contextmenu items can now access the name, the command and whatever else you might need."

There's no mention of changing data contexts, visual trees, etc.

Here's my ViewModel:

public class ViewModel
{
  public class ContextAction : INotifyPropertyChanged
  {
    public string HeaderText;
    public event PropertyChangedEventHandler PropertyChanged;
    public void RaisePropertyChanged(string property)
    {
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
    }
  }

  public ObservableCollection<ContextAction> ContextMenuActions { get; set; }

  public ViewModel()
  {
    ContextMenuActions = new ObservableCollection<ContextAction>();
    ContextMenuActions.Add(new ContextAction { HeaderText = "Foo" });
    ContextMenuActions.Add(new ContextAction { HeaderText = "Bar" });
    ContextMenuActions.Add(new ContextAction { HeaderText = "Baz" });
  }
}

...and my XAML:

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <local:ViewModel />
    </Window.DataContext>

    <Grid Background="red">
        <Grid.ContextMenu>
            <ContextMenu ItemsSource="{Binding ContextMenuActions}">
                <ContextMenu.ItemTemplate >
                    <DataTemplate DataType="MenuItem">
                        <MenuItem Header="{Binding HeaderText}" />
                    </DataTemplate>
                </ContextMenu.ItemTemplate>
            </ContextMenu>
        </Grid.ContextMenu>
    </Grid>
</Window>

I can see that the items get added to the context menu. Right-clicking on the grid produces a menu with three blank items. However, the header bindings are not working (each menu item is blank). Did I miss something from the answer I linked? Do I need to make some sort of proxy class as mentioned here? That seems rather convoluted for a simple task like making a context menu and isn't even hinted at in the first answer I linked to.

1

1 Answers

1
votes

You can only bind to properties, not fields.

public string HeaderText {get; set;}

enter image description here