I don't understand how to add binding to the button inside DataGrid. Can you please help me?
What I have: I can connect any simple button and I can give it some functionality. But when I want to do a binding to the button inside DataGrid I catch errors. Current error for the code below is AVLN2000 Unable to resolve property or method of name 'AddRowCommand' on type 'aa3.ViewModels.Item'. And without any parameter I still see a error.
My code
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:aa3.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="aa3.Views.MainWindow"
x:DataType="vm:MainWindowViewModel"
Icon="/Assets/avalonia-logo.ico"
Title="aa3">
<Window.DataContext>
<vm:MainWindowViewModel />
</Window.DataContext>
<Grid>
<StackPanel Orientation="Vertical" Margin="0" HorizontalAlignment="Left">
<Button Content="btn01" Width="50" Height="30" Margin="0,0,0,0" Command="{Binding SomeCommand}"/>
<Button Content="btn02" Width="50" Height="30" Margin="0,0,0,0" Command="{Binding AnotherCommand}"/>
<Button Content="btn03" Width="50" Height="30" Margin="0,0,0,0"/>
<DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False"
Margin="20"
IsReadOnly="True"
CanUserReorderColumns="True"
CanUserResizeColumns="True"
CanUserSortColumns="False"
GridLinesVisibility="All"
BorderThickness="1" BorderBrush="Gray">
<DataGrid.Columns>
<DataGridTextColumn Header="First Name" Binding="{Binding Number}"/>
<DataGridTextColumn Header="Last Name" />
<DataGridTemplateColumn Header="Action" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="Add Row" Command="{Binding AddRowCommand}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</StackPanel>
</Grid>
</Window>
also the code in namespace aa3.ViewModels
public partial class MainWindowViewModel : ObservableObject
{
public ObservableCollection<Item> Items { get; set; }
private int Counter { get; set; } = 1;
public MainWindowViewModel()
{
Items = new ObservableCollection<Item>
{
new Item(Counter++),
new Item(Counter++)
};
AddRowCommand = new RelayCommand<Object>(AddRow);
SomeCommand = new RelayCommand(SomeAction);
AnotherCommand = new RelayCommand<Object>(AnotherAction);
}
public IRelayCommand AddRowCommand { get; }
private void AddRow(Object currentItem)
{
Item item = currentItem as Item;
if (item == null)
{
Trace.WriteLine("error");
return;
}
var index = Items.IndexOf(item);
Items.Insert(index + 1, new Item (Counter++));
}
public IRelayCommand SomeCommand { get; }
private void SomeAction()
{
Trace.WriteLine("Some command");
}
public IRelayCommand AnotherCommand { get; }
private void AnotherAction(Object obj)
{
Trace.WriteLine("Another command");
}
}
public class Item : ObservableObject
{
public Item (int n)
{
Number = n;
}
public int Number { get; set; }
}
I tried to delete all parameters from my method but it doesn't work still, also I checked the documentation of Avalonia but looks like this question is not written there.
I got the answer from the community of Avalonia via the https://t.me/Avalonia link.
I needed to add into the tag Window the parameter x:Name="Root"
, and my command inside the button should look like:
Command="{Binding #Root.((vm:MainWindowViewModel)DataContext).AddRowCommand}"
Also, they gave me the link to the documentation, which includes instructions on how to bind a concretely named section: https://docs.avaloniaui.net/docs/guides/data-binding/binding-to-controls#binding-to-a-named-control