0

I want to add a method to my custom control which I can call from a button using command binding, in my MainWindow.xaml. I've come across a few solutions online, however one of them didn't appear to work and the other did. Can someone explain to me the correct way to set this up. The first solution produces and error as mentioned below. The second solution works but I'm not sure of any pros/cons.

Solution 1 - broken

public partial class MyControl : Control
{
    ...
    public static readonly RoutedCommand AlignLeftCommand = null;

    static MyControl()
    {
        binding = new CommandBinding();
        binding.Command = AlignLeftCommand;
        binding.Executed += new ExecutedRoutedEventHandler(AlignLeft_Executed);
        CommandManager.RegisterClassCommandBinding(typeof(MyControl), binding);
    }
}

Error:

Severity Code Description Project File Line Error CS0120 An object reference is required for the non-static field, method, or property...

Solution 2

public partial class MyControl : Control
{
    ...
    public static readonly RoutedCommand AlignLeftCommand = new RoutedCommand();

    public MyControl()
    {
        this.CommandBindings.Add(new CommandBinding(MyControl.AlignLeftCommand, AlignLeft_Executed, null));
    }
}

Here is the button calling the method.

<StackPanel Orientation="Horizontal">
    <Button Content="Left Edges" FontSize="8"
            Command="{x:Static JM:MyControl.AlignLeftCommand}"
            CommandTarget="{Binding ElementName=mycontrol}"/>
</StackPanel>
1
  • 1
    Is your application MVVM or code-behind? Commented Feb 4, 2016 at 14:21

1 Answer 1

1

At first, you should define a command binding on the Window like that(create handlers for Executed and CanExecuteevents):

<Window x:Class="CommandBindingWPF.MainWindow"
        ...The code omitted for the brevity...
        Title="MainWindow" Height="350" Width="525">
    <Window.CommandBindings>
        <CommandBinding Command="ApplicationCommands.New" Executed="CommandBinding_Executed" CanExecute="CommandBinding_CanExecute" />
    </Window.CommandBindings>

and declare your Button ix xaml:

<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
    <Button Command="ApplicationCommands.New">New</Button>
</StackPanel>

Handlers should be created in code-behind after you command binding created:

private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
   MessageBox.Show("Hello from Command");
}

private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{      }

Update:

For MVVM application:

public class RelayCommand : ICommand
{
    #region Fields

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

    #endregion // Fields

    #region Constructors

    public RelayCommand(Action<object> execute)
        : this(execute, null)
    {
    }

    public RelayCommand(Action<object> execute, Predicate<object> canExecute)
    {
        if (execute == null)
            throw new ArgumentNullException("execute");

        _execute = execute;
        _canExecute = canExecute;
    }
    #endregion // Constructors

    #region ICommand Members

    public bool CanExecute(object parameter)
    {
        return _canExecute == null ? true : _canExecute(parameter);
    }

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

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

    #endregion // ICommand Members
}

Then create a property in your viewModel. For instance:

public class YourViewModel
{
    public RelayCommand YourCommand { get; set; }
    public YourViewModel()
    {
        YourCommand = new RelayCommand(DoSmth, CanDoSmth);
    }

    private void DoSmth(object obj)
    {
        Message.Box("Hello from viewModel"); 
    }

    private bool CanDoSmth(object obj)
    {
       //you could implement your logic here. But by default it should be  
       //set to true
       return true;
    }
}

And XAML should be look like:

<Button Content="Click me!" Command="{Binding YourCommand}"/> 

To get acquainted with MVVM, I recommend you to read Rachel Lim's blog. She has a talent to teach people and she can explain by simple terms. Read Rachel Lim's blog. To get acquainted with MVVM commands see that post

Sign up to request clarification or add additional context in comments.

9 Comments

The command function actually exists within my control though. How can i properly set that up?
i dont think this answers the question completely.
@JokerMartini is it MVVM or code-behind application?
Not super important really . Ideally close to mvvm if possible
ideally close to mvvm
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.