1

I want to pass the ViewModel parameter(class variable) when I click the buttons in the View. When specifying a string, everything comes true, but I need to pass a non-string value from the View class(function AddNewField).

Main.xaml:

...
<Button
    x:Name="ButtonAddingField"
    CommandParameter="{Binding Path=Myprop}"
    Command="{Binding Path=Myprop, RelativeSource={RelativeSource AncestorType=UserControl}}" />
...

Main.cs:

...
    private Color myprop;

    public Color Myprop
    {
        get => myprop;
    }


...
this.DataContext = new FieldCollectionViewModel(fields); // fields - List<*my Model*>

...

FieldCollectionViewModel.cs:

...
private DelegateCommand<object> addFieldCommand;

public ICommand AddFieldCommand {
    get {
        if (addFieldCommand == null) addFieldCommand = new DelegateCommand<object>(AddNewField);
        return addFieldCommand;
    }
}

private void AddNewField(object parameter)
{
    // !!! parameter = ALWAYS NULL
}
...

and my DelegateCommand.cs:

    ...
public class DelegateCommand<T> : ICommand
{
    #region Constructors

    /// <summary>
    ///     Constructor
    /// </summary>
    public DelegateCommand(Action<T> executeMethod)
        : this(executeMethod, null, false)
    {
    }

    /// <summary>
    ///     Constructor
    /// </summary>
    public DelegateCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod)
        : this(executeMethod, canExecuteMethod, false)
    {
    }

    /// <summary>
    ///     Constructor
    /// </summary>
    public DelegateCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod, bool isAutomaticRequeryDisabled)
    {
        if (executeMethod == null) throw new ArgumentNullException("executeMethod");

        _executeMethod = executeMethod;
        _canExecuteMethod = canExecuteMethod;
        _isAutomaticRequeryDisabled = isAutomaticRequeryDisabled;
    }

    #endregion Constructors

    #region Public Methods

    /// <summary>
    ///     Method to determine if the command can be executed
    /// </summary>
    public bool CanExecute(T parameter)
    {
        if (_canExecuteMethod != null) return _canExecuteMethod(parameter);
        return true;
    }

    /// <summary>
    ///     Execution of the command
    /// </summary>
    public void Execute(T parameter)
    {
        if (_executeMethod != null) _executeMethod(parameter);
    }

    /// <summary>
    ///     Raises the CanExecuteChaged event
    /// </summary>
    public void RaiseCanExecuteChanged()
    {
        OnCanExecuteChanged();
    }

    /// <summary>
    ///     Protected virtual method to raise CanExecuteChanged event
    /// </summary>
    protected virtual void OnCanExecuteChanged()
    {
        CommandManagerHelper.CallWeakReferenceHandlers(_canExecuteChangedHandlers);
    }

    /// <summary>
    ///     Property to enable or disable CommandManager's automatic requery on this command
    /// </summary>
    public bool IsAutomaticRequeryDisabled {
        get => _isAutomaticRequeryDisabled;
        set {
            if (_isAutomaticRequeryDisabled != value)
            {
                if (value)
                    CommandManagerHelper.RemoveHandlersFromRequerySuggested(_canExecuteChangedHandlers);
                else
                    CommandManagerHelper.AddHandlersToRequerySuggested(_canExecuteChangedHandlers);
                _isAutomaticRequeryDisabled = value;
            }
        }
    }

    #endregion Public Methods

    #region ICommand Members

    /// <summary>
    ///     ICommand.CanExecuteChanged implementation
    /// </summary>
    public event EventHandler CanExecuteChanged {
        add {
            if (!_isAutomaticRequeryDisabled) CommandManager.RequerySuggested += value;
            CommandManagerHelper.AddWeakReferenceHandler(ref _canExecuteChangedHandlers, value, 2);
        }
        remove {
            if (!_isAutomaticRequeryDisabled) CommandManager.RequerySuggested -= value;
            CommandManagerHelper.RemoveWeakReferenceHandler(_canExecuteChangedHandlers, value);
        }
    }

    bool ICommand.CanExecute(object parameter)
    {
        // if T is of value type and the parameter is not
        // set yet, then return false if CanExecute delegate
        // exists, else return true
        if (parameter == null &&
            typeof(T).IsValueType)
            return _canExecuteMethod == null;
        return CanExecute((T)parameter);
    }

    void ICommand.Execute(object parameter)
    {
        Execute((T)parameter);
    }

    #endregion ICommand Members

    #region Data

    private readonly Action<T> _executeMethod;
    private readonly Func<T, bool> _canExecuteMethod;
    private bool _isAutomaticRequeryDisabled;
    private List<WeakReference> _canExecuteChangedHandlers;

    #endregion Data
}
...

How can I solve my problem?

UPDATE. I changed my code, now it is working Thanks to @mm8

RookieCPP
  • 83
  • 7

1 Answers1

0

Myprop must be a public property of the DataContext of the Button for your current binding to work.

If it's a property of the parent UserControl, you could bind to it using a RelativeSource:

CommandParameter="{Binding Path=Myprop, RelativeSource={RelativeSource AncestorType=UserControl}}"

Note that you can only bind to public properties. You cannot bind to fields.

mm8
  • 163,881
  • 10
  • 57
  • 88