XAML 如何将视图构造函数中的ReactiveCommand绑定到ItemTemplate中的Button

fxnxkyjh  于 2023-03-10  发布在  React
关注(0)|答案(1)|浏览(166)

bounty已结束。此问题的答案可获得+400的信誉奖励。奖励宽限期将在17小时后结束。Miljac正在寻找来自信誉良好来源的答案:如果我想要的东西是不可能的,我希望得到一个解释,为什么是这样,以更好地了解事情是如何工作的

我正在使用ReactiveUI和Avalonia与C#。
我在MyItemsControl的ItemTemplate内的按钮上执行命令时遇到问题。MyView和MyItemsControl正确显示,但当我单击ItemsTemplate内生成的按钮时,没有任何React,即使绑定到命令也没有报告任何错误。以下是我的代码模型。
视图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代码隐藏:

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);
    }
}

视图模型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
}

下面是自定义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代码隐藏:

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);
    }
}

代码编译良好,并按预期显示MyViewMyUserControl,但当我单击由ItemTemplate生成的按钮时,没有任何React。
我还尝试将RemoveThisItemCommandProperty声明为StyledProperty,并尝试在MyUserControl代码中使用ICommand而不是ReactiveCommand。
如果我使用ICommand而不是ReactiveCommand,并从MyView中的xaml而不是构造函数进行绑定,它将按预期工作,并将参数传递给命令:

<mycontrols:MyItemsControl
        Name="MyItemsControl1"
        RemoveThisItemCommand="{Binding RemoveItemCommand}">

但是我想在构造函数中绑定,因为documentation here建议这样做。有没有办法在视图构造函数中绑定这个按钮命令和参数?

tjvv9vkg

tjvv9vkg1#

降低绑定复杂性。
SomeItem对象中,创建command属性并将其绑定到button命令。

<ItemsControl Items={Binding #ParentUserControl.SomeItems}>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Button
                Command={Binding RemoveThisItemCommand}
                CommandParameter="{Binding .}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

在创建SomeItem示例列表时,将主视图模型命令注入该属性。

相关问题