简体   繁体   中英

Dynamic Menu from ObservableCollection: Passing Item as parameter

I'm trying to change a property in my main ViewModel based on the click from a menu, which is populated by a list of objects.

ViewModel

public class MyViewModel : ObservableObject
{
    /// <summary>
    /// Private field for products
    /// </summary>
    private ObservableCollection<Product> products;

    /// <summary>
    /// Private field for the product
    /// </summary>
    private Product product;

    /// <summary>
    /// Gets or sets the Product
    /// </summary>
    public Product Product
    {
        get => this.product;
        set
        {
            this.product = value;
            this.RaisePropertyChangedEvent("Product");
        }
    }

    /// <summary>
    /// Gets or sets a collection of Products
    /// </summary>
    public ObservableCollection<Product> Products
    {
        get => this.plant;
        set
        {
            this.plant = value;
            this.RaisePropertyChangedEvent("Products");
        }
    }

    public ICommand ChangeProduct => new DelegateCommand(p => this.SetProduct((Product)p), p => p is Product);

    private void SetProduct (Product product) => this.Product = product;
}

I'm trying to change the Product by clicking a MenuItem in a Menu .

<Menu Grid.Row="0" Background="White">
    <MenuItem Header="Products">
        <MenuItem Name="ProductMenu" Header="Change Product" ItemsSource="{Binding Products}" DisplayMemberPath="Name" Command="{Binding ChangeProduct}" CommandParameter="{Binding ElementName=ProductMenu}"/>
    </MenuItem>
</Menu>

This, however, isn't working. How do I bind the Product attached to the clicked generated MenuItem as a parameter in my ViewModel?

Xaml could be something like this:

<Menu Grid.Row="0" Background="White">
   <MenuItem Header="Products"   >
       <MenuItem Name="ProductMenu" Header="Products"  ItemsSource="{Binding Products}"  DisplayMemberPath="Name" >
                    <MenuItem.ItemContainerStyle>
                        <Style TargetType="MenuItem">
                             <Setter Property="Command" Value="{Binding  ElementName=ProductMenu, Path=DataContext.ChangeProduct}"/>
                            <Setter Property="CommandParameter" Value="{Binding}"/>
                        </Style>
                    </MenuItem.ItemContainerStyle>
                </MenuItem>

   </MenuItem>
</Menu>

Just change the CommandParameter binding to just CommandParameter="{Binding}" , ie remove the path:

<MenuItem Name="ProductMenu"
        Header="Change Product" 
        ItemsSource="{Binding Products}" 
        DisplayMemberPath="Name" 
        Command="{Binding ChangeProduct}" 
        CommandParameter="{Binding}"/>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM