Binding Command on dynamically loaded menuitem

送分小仙女□ 提交于 2021-01-29 17:27:05

问题


I am successfully populating a menuitem with a list of cars. I want each car in the menuitem to be able to fire a command "RemoveCarCommand". On a dynamically loaded menuitem of cars (or anything), I know I need to have the command assigned to each car that is in the menuitem, but I cannot figure out the XAML to do that. Can someone help?

<MenuItem Header="Remove Car" ItemsSource="{Binding AvailableCars}">
    <MenuItem.ItemContainerStyle>
        <Style>
            <Setter Property="MenuItem.Command" Value="{Binding RemoveCarCommand, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}"/>
        </Style>
    </MenuItem.ItemContainerStyle>
</MenuItem>

回答1:


I think you are over thinking your issue, if each menuitem is going to perform the same task just on a different "car", you can just point all of them to the same event handler for click then access the datacontext to find out which one was clicked and thus which car to remove.

<MenuItem Header="Remove Car" ItemsSource="{Binding AvailableCars}" click"removeCar"/>

in CB

private void removeCar(object sender, EventArgs e)
{
    Car car = ((sender as Button).DataContext as Car);

    car.remove();
    //OR
    CarsList.Remove(car);
}

If you absolutely MUST use the command MVVM binding this is what you need:

public class RelayCommand : ICommand
{
    #region Fields

    readonly Action<object> _execute;
    readonly Predicate<object> _canExecute;

    #endregion // Fields

    #region Constructors

    /// <summary>
    /// Creates a new command that can always execute.
    /// </summary>
    /// <param name="execute">The execution logic.</param>
    public RelayCommand(Action<object> execute)
        : this(execute, null)
    {
    }

    /// <summary>
    /// Creates a new command.
    /// </summary>
    /// <param name="execute">The execution logic.</param>
    /// <param name="canExecute">The execution status logic.</param>
    public RelayCommand(Action<object> execute, Predicate<object> canExecute)
    {
        if (execute == null)
            throw new ArgumentNullException("execute");

        _execute = execute;
        _canExecute = canExecute;
    }

    #endregion // Constructors

    #region ICommand Members

    [DebuggerStepThrough]
    public bool CanExecute(object parameters)
    {
        return _canExecute == null ? true : _canExecute(parameters);
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public void Execute(object parameters)
    {
        _execute(parameters);
    }

    #endregion // ICommand Members
}

Then add this in your class obj for Car:

public class Car
{
    private ICommand _ClickCommand;
    public ICommand ClickCommand
    {
        get
        {
            if (_ClickCommand == null)
            {
                _ClickCommand = new RelayCommand(param => this.Click(param, EventArgs.Empty));
            }
            return _ClickCommand;
        }
    }
}

And this is how you bind to it in WPF:

                <Menu.ItemContainerStyle>
                    <Style TargetType="{x:Type MenuItem}">
                        <Setter Property="Command" Value="{Binding ClickCommand}"/>
                    </Style>
                </Menu.ItemContainerStyle>


来源:https://stackoverflow.com/questions/35925103/binding-command-on-dynamically-loaded-menuitem

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!