Fire RelayCommand from DataGrid with AvaloniaUI and Community Toolkit MVVM

91 views Asked by At

I'm trying to fire a RelayCommand located in the ViewModel from a DataGridCell in the View, with the parameter being the object in the current DataGridRow.

To reproduce my problem I recreated the first example from Avalonia DataGrid guide page, and just added some simple Community Toolkit MVVM touch like [ObservableProperty] on variables.

Then I created a RelayCommand like so in the MainWindowViewModel:

[RelayCommand]
public void Foo(Person person)
{
    // Set breakpoint here
    person.FirstName = "Changed";
}

And I tried to call it from a button in the View:

<Button Command="{Binding FooCommand}" HorizontalAlignment="Center">Fires Relay Command correctly</Button>

It works correctly and when debugging I break correctly into the relay command, but when i try to do the same inside a DataGridTemplateColumn, even after setting the DataContext, it doesn't work and throws the error Unable to resolve property or method of name 'FooCommand' on type 'System.Object'.

I have tried:

<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        ...
        x:Name="root"/>
...
<DataTemplate DataType="models:Person">
    <Button Command="{Binding #root.DataContext.FooCommand}"
        CommandParameter="{Binding}"
        HorizontalAlignment="Center">Can't Find RelayCommand</Button>
</DataTemplate>
<DataTemplate DataType="models:Person">
    <Button Command="{Binding Path=DataContext.FooCommand,
                          RelativeSource= {RelativeSource FindAncestor,
                          AncestorType={x:Type DataGrid}}}"
        CommandParameter="{Binding}"
        HorizontalAlignment="Center">Can't Find RelayCommand</Button>
</DataTemplate>
<DataTemplate DataType="models:Person">
    <Button Command="{Binding #root.DataContext.FooCommand}"
        CommandParameter="{Binding}"
        HorizontalAlignment="Center">Can't Find RelayCommand</Button>
</DataTemplate>

And none of them worked, I even tried changing DataType to set the vm directly, knowing that it will probably lose the Person object of theCommandParameter, but even then, it builds and runs without errors, but it doesn't fire the RelayCommand:

<DataTemplate DataType="vm:MainWindowViewModel">
    <Button Command="{Binding FooCommand}"
        CommandParameter="{Binding}"
        HorizontalAlignment="Center">Doesn't Fire RelayCommand</Button>
</DataTemplate>
1

There are 1 answers

0
Saliom On BEST ANSWER

When using Compiled Binding (enabled by default when creating a new Avalonia Project), you have to explicitly cast the DataContext like so to make it work:

<DataTemplate DataType="models:Person">
    <Button Command="{Binding #root.((vm:MainWindowViewModel)DataContext).FooCommand}"
    CommandParameter="{Binding}"
    HorizontalAlignment="Center">Fires Relay Command correctly</Button>
</DataTemplate>