ICommand 在 Silverlight 用户控件中不起作用

ICommand not working in Silverlight User control

我有一个带网格的 UserControlBase。网格包含一个带有操作的列。

<sdk:DataGridTemplateColumn Header="Action">
    <sdk:DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <StackPanel>
                 <Button Style="{StaticResource DataGridButton}"  Command="{Binding Source={StaticResource NewsViewModel}, Path=ModifyNewsCommand}" Content="Modify" />
             </StackPanel>
         </DataTemplate>
     </sdk:DataGridTemplateColumn.CellTemplate>
 </sdk:DataGridTemplateColumn>

我的问题出在 Command 上。它向我抛出技术错误,这是我的第一个问题,我不知道如何让这个应用程序向我抛出真正的错误消息。

在我的用户控件后面的代码中,我注册了事件:

protected void RegisterMessages()
{
    Messenger.Default.Register<string>(this, "NewNewsBtn_Click", NewNewsBtn_Click);
    Messenger.Default.Register<string>(this, "ModifyNewsBtn_Click", ModifyNewsBtn_Click);
}

在我的构造函数中:

public NewsWindow(int underlyingId)
{
    InitializeComponent();
    this.RegisterMessages();
    viewModel = new NewsViewModel(underlyingId);
    ucNewsPanel.DataContext = viewModel;
}

我的视图模型 (NewsViewModel)

public ICommand ModifyNewsCommand
{
    get
    {
        return new RelayCommand<string>(e =>
        {
            Messenger.Default.Send(string.Empty, "ModifyNewsBtn_Click");
        });
    }
}

奇怪的是我的 NewNewsBtn 在工作,而我的 ModifyNewsBtn 没有。

此按钮位于网格之外,因此它的工作原理可能有所不同。

<Button x:Name="NewNewsBtn" MaxHeight="50" MaxWidth="100" Command="{Binding Path=NewNewsCommand}" Content="Add New" />

你的语法看起来没问题:

<Button Style="{StaticResource DataGridButton}" Content="Modify" 
  Command="{Binding Source={StaticResource NewsViewModel}, Path=ModifyNewsCommand}"/>

但是你在代码中设置了 viewModel。你在 XAML 中创建 StaticResource 我说得对吗?如果是,则只需从代码隐藏中删除设置 DataContext,因为下一行 Command="{Binding Source={StaticResource NewsViewModel}, Path=ModifyNewsCommand}" 将在您的 viewModel 的另一个实例中看到。 (因为您已经创建了 NewsViewModel 的两个实例作为 StaticResource 和代码隐藏)

更新:
当我将参数传递给我的视图模型时,我需要代码隐藏中的 DataContext。如果我从后面的代码中删除它,有什么办法可以做到这一点?
那么你应该从 Command:

的绑定中删除 StaticResource
<Button Style="{StaticResource DataGridButton}" Command="{Binding ModifyNewsCommand}" 
                                                                    Content="Modify"/>

因为您正在引用 NewsViewModel 的另一个实例。

您的 DataGrid 将绑定到某个集合,每个项目一行。现在该项目是一行的 DataContext。您需要做的是将 "Modify"-button 绑定到父 DataContext。如果您使用的是 silverlight5,则可以使用 AncestorBinding:

<Button
    Content="Modify"
    Command="{Binding
        Path=DataContext.ModifyNewsCommand,
        RelativeSource={RelativeSource AncestorType=UserControl}}"/>