I am using ReactiveUI and Avalonia with C#.
I have problem with executing command on a Button inside ItemTemplate of MyItemsControl
. MyView and MyItemsControl are correctly displayed but when I click a Button generated inside ItemsTemplate, nothing happens, even though binding to command does not report any errors. Here is a mock-up of my code.
View MyView
:
<UserControl
...
x:Class="MyApp.MyView"
xmlns:vm="using:MyApp.ViewModels"
xmlns:mycontrols="clr-namespace:MyApp.MyContorls"
DataContext="vm:MyViewModel">
<!--Other code-->
<mycontrols:MyItemsControl
Name=“MyItemsControl1“>
<!--Other code-->
</UserControl>
MyView
code behind:
public partial class MyView : IViewFor<MyViewModel>
{
public MyItemsControl MyItemsControl1 => this.FindControl<MyItemsControl>("MyItemsControl1");
public MyView()
{
this.WhenActivated(disposables =>
{
this.BindCommand(ViewModel, vm => vm.RemoveItemCommand, v => v.MyItemsControl1.RemoveThisItemCommand)
.DisposeWith(disposables);
}
AvaloniaXamlLoader.Load(this);
}
}
ViewModel MyViewModel
:
public class MyViewModel : ReactiveObject
{
//other code
private ReactiveCommand<SomeItem, Unit>? _removeItemCommand;
public ReactiveCommand<SomeItem, Unit>? RemoveItemCommand
{
get { return _removeItemCommand; }
private set { this.RaiseAndSetIfChanged(ref _removeItemCommand, value); }
}
//other code
}
Here is custom UserControl MyItemsControl
:
<UserControl
x:Class="MyApp.MyControls.MyItemsControl"
Name=“ParentUserControl“>
<!--Other code-->
<ItemsControl
Items={Binding #ParentUserControl.SomeItems}>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button
Command={Binding #ParentUserControl.RemoveThisItemCommand}
CommandParameter="{Binding .}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</UserControl>
MyUserControl
code behind:
public partial class MyUserControl : UserControl
{
public static readonly DirectProperty<MyItemsControl, ReactiveCommand<SomeItem, Unit>> RemoveThisItemCommandProperty =
AvaloniaProperty.RegisterDirect<MyItemsControl, ReactiveCommand<SomeItem, Unit>>(nameof(RemoveThisItemCommand), x => x. RemoveThisItemCommand, (x, v) => x.RemoveThisItemCommand = v);
private ReactiveCommand<SomeItem, Unit> _removeThisItemCommand;
public ReactiveCommand<SomeItem, Unit> RemoveThisItemCommand
{
get => _removeThisItemCommand;
set => SetAndRaise(RemoveThisItemCommandProperty, ref _removeThisItemCommand, value);
}
}
Code compiles fine, and displays MyView
and MyUserControl
as expected, but nothing happens when I click a button which is generated by ItemTemplate.
I also tried declaring RemoveThisItemCommandProperty as a StyledProperty, and tried using ICommand instead of ReactiveCommand in MyUserControl
code behind. But nothing works.
If I use ICommand instead of ReactiveCommand, and bind from xaml in MyView
instead of constructor it works as expected and parameter is passed through to command:
<mycontrols:MyItemsControl
Name="MyItemsControl1"
RemoveThisItemCommand="{Binding RemoveItemCommand}">
But I wanted to bind in constructor, since it is recommended to do so by documentation here. Is there a way to bind this button command with parameter in view constructor?