How to Bind to a Command without ReactiveUI
Sometimes you just want to call a method when a button is clicked without the full ceremony of creating a reactive command, using the ReactiveUI framework.
To see how to how to bind to a command with ReactiveUI, see here.
Avalonia UI data binding allows you to implement directly both a view model method that performs an action, and a property that can control whether the method can execute.
For example, using the XAML as follows:
<Window xmlns="https://github.com/avaloniaui">
...
<StackPanel Margin="20">
<Button Command="{Binding PerformAction}"
CommandParameter="From the button, without ReactiveUI">
Run the example</Button>
</StackPanel>
</Window>
You can write a view model capable of running the action, like this
namespace AvaloniaGuides.ViewModels
{
public class MainWindowViewModel
{
public void PerformAction(object msg)
{
Debug.WriteLine($"The action was called. {msg}");
}
}
}
![](/ru/assets/images/bind-method-0233991fda4964f5ef62ba1b3bf5dc1e.gif)
Can Execute?
Avalonia UI data binding provides a simple way of implementing a 'can execute?' feature using a naming convention.
If you need to have execution dependent on the value of a command parameter or a view model property, then you can write a second Boolean method to check if the action m,ethod can execute.
To make this work, Avalonia UI uses the naming convention that the Boolean method has the same root name as the action method, but with the added prefix 'Can'.
For example:
namespace AvaloniaGuides.ViewModels
{
public class MainWindowViewModel
{
public void PerformAction(object msg)
{
Debug.WriteLine($"The action was called. {msg}");
}
public bool CanPerformAction(object msg)
{
if (msg!=null) return !string.IsNullOrWhiteSpace( msg.ToString() );
return false;
}
}
}
So, extending the example XAML to supply the parameter (string) from a text box:
<StackPanel Margin="20">
<TextBox Margin="0 5" x:Name="message"
Watermark="Add a message to enable the button"/>
<Button Command="{Binding PerformAction}"
CommandParameter="{Binding #message.Text}">
Run the example
</Button>
</StackPanel>