【问题标题】:ICommand not working in Silverlight User controlICommand 在 Silverlight 用户控件中不起作用
【发布时间】:2016-06-01 07:58:34
【问题描述】:

我有一个带有网格的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" />

【问题讨论】:

  • 为什么在 Binding 中使用 StaticResource 而不仅仅是访问 DataContext?在我看来,这是您的 Button 无法正常工作的原因。
  • 我猜这部分是错误的Command="{Binding Source={StaticResource NewsViewModel}, Path=ModifyNewsCommand}"
  • @Martin - 如果删除 StaticResource 并只保留路径,则它不起作用。它没有向我抛出错误,但它没有进入方法。
  • 我想我知道为什么。看我的回答。

标签: wpf silverlight mvvm


【解决方案1】:

您的 DataGrid 将绑定到某个集合,每个项目都有一行。现在该项目是一行的 DataContext。您需要做的是将您的“修改”按钮绑定到父 DataContext。如果您使用的是 silverlight5,您可以使用 AncestorBinding:

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

【讨论】:

    【解决方案2】:

    你的语法看起来不错:

    <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 的另一个实例。

    【讨论】:

    • 当我将参数传递给我的视图模型时,我需要后面的代码中的DataContext。如果我从后面的代码中删除它,我可以通过什么方式做到这一点?
    • 更新后的答案不起作用。它找不到视图模型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-16
    • 1970-01-01
    • 2018-08-14
    • 2016-04-27
    • 1970-01-01
    相关资源
    最近更新 更多