DelegateCommand<T> 在 DataTemplate 中绑定时出现异常

DelegateCommand<T> Exception When Binding in DataTemplate

我想我在 Prism for Windows Runtime 库中发现了一个错误,但我想知道是否有解决方法或解决问题的方法,而无需我自己分叉项目...

我正在尝试在 ItemsControl 中显示项目列表。每个项目都有一个按钮,单击该按钮时应该在父控件的数据上下文中执行命令并将项目的 ID 作为命令参数传递。基本上,我正在尝试呈现项目列表并为每个项目设置一个删除按钮。为实现这一目标,我遵循了这个 code sample,到目前为止我发现这是完成这一壮举的唯一干净的方法。

不幸的是,Prism 为 Windows 运行时实现的 DelegateCommand<T> class 似乎不能很好地与 XAML 绑定解析器一起使用。当一切都连接好后,我在页面尝试呈现时收到此异常:

Failed to assign to property 'Windows.UI.Xaml.Controls.Primitives.ButtonBase.Command'. [Line: 61 Position: 49]

我创建了一个新项目并简化了我的生产示例以测试我的理论,即这是 DelegateCommand<T> 的一个问题(这是允许将参数传递给委托方法所必需的)。我实现了两个命令,一个使用 DelegateCommand<T>,一个只使用 DelegateCommand。使用 DelegateCommand 的那个不会导致异常,但我失去了接受命令参数的能力,这意味着我无法确定要删除的项目。

XAML:

<ItemsControl Name="TestControl" Grid.Row="1" ItemsSource="{Binding MyItems}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Button Content="{Binding}" Command="{Binding DataContext.BrokenCommand, ElementName=TestControl}" CommandParameter="1" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

视图模型:

public DelegateCommand<int> BrokenCommand { get; set; }
public DelegateCommand WorkingCommand { get; set; }

public List<string> MyItems { get { return new List<string> {"A", "B", "C"}; } }

public MainPageViewModel(INavigationService navigationService)
{
    BrokenCommand = new DelegateCommand<int>(BrokenMethod);
    WorkingCommand = new DelegateCommand(WorkingMethod);
}

private void BrokenMethod(int i)
{
    throw new NotImplementedException();
}

private void WorkingMethod()
{
    throw new NotImplementedException();
}

试试这个

    BrokenCommand = new DelegateCommand<string> 
    (id => BrokenMethod(Convert.ToInt32((id));

我刚刚对其进行了测试,如果您将 T 更改为字符串,它会起作用,因为它是一个字符串。

希望有人能解释为什么:)

在另一个答案的启发下,我终于完成了这项工作。我不确定为什么,但是委托命令的 属性 签名导致了异常。将 DelegateCommand<int> 更改为 DelegateCommand<object> 后一切正常。现在我可以将对象转换为 int 然后从那里开始。如果有人能解释为什么会发生这个问题,那就太好了!

XAML:

<ItemsControl Name="TestControl" Grid.Row="1" ItemsSource="{Binding MyItems}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Button Content="{Binding}" Command="{Binding DataContext.WorkingCommand, ElementName=TestControl}" CommandParameter="1"></Button>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

查看模型:

public DelegateCommand<object> WorkingCommand { get; set; }

public List<string> MyItems { get { return new List<string> {"A", "B", "C"}; } }

public MainPageViewModel()
{
    WorkingCommand = new DelegateCommand<object>(WorkingMethod);
}

private void WorkingMethod(object id)
{
    throw new NotImplementedException();
}