【问题标题】:How to fire event from button inside datagrid in silverlight and MVVM如何在silverlight和MVVM中从数据网格内的按钮触发事件
【发布时间】:2010-12-09 08:24:38
【问题描述】:

我在数据网格的第一列有按钮。我正在使用 MVVM 并尝试将命令绑定到 ViewModel 中的命令,但是当我单击每一行中的按钮时,它不起作用(它不会在 ViewModel 中调用命令)但是如果我将该按钮移出数据网格,它会正常工作。

如何从 MVVM 中数据网格内的按钮触发事件?

更新 1:

XAML 的代码是:

<datagrid:DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
        <StackPanel Orientation="Horizontal" 
                        VerticalAlignment="Center">
            <Button x:Name="button" Content="View" Margin="5" DataContext="{StaticResource XDataContext}">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Click">
                        <i:InvokeCommandAction Command="{Binding ViewOrganizationCommand}"
                                                CommandParameter="{Binding ElementName=dtgOrganizations, Path=SelectedItem}" />
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </Button>
        </StackPanel>
    </DataTemplate>
</datagrid:DataGridTemplateColumn.CellTemplate>

ViewModel 的代码是:

public ViewModelCommand ViewOrganizationCommand { get; set; }

【问题讨论】:

  • 查看您的 xaml 和 VM 代码会有所帮助。请添加。
  • 按照您的建议添加源代码:)
  • 您是否遇到任何绑定异常?您可以在“输出”窗口中看到它。

标签: silverlight mvvm


【解决方案1】:

为什么不直接绑定到 Button.Command,而不是使用 EventTrigger,像这样呢?

<Button 
    ...other properties...
    Command="{Binding ViewOrganizationsCommand}"
    CommandParameter="{Binding}"/>

那将绑定命令,并将CommandParameter设置为Button的DataContext,这想必是绑定参数的好东西。如果不是,只需将 CommandParameter 绑定到其他可以帮助您唯一识别被点击的特定行的东西。

【讨论】:

    【解决方案2】:

    This article 带来了 DataContextProxy 的解决方案。应用此解决方案可以编写类似 Austin Lamb 的答案的按钮代码。

    【讨论】:

      【解决方案3】:

      使用事件触发器的命令绑定看起来不错(这就是我一直这样做的方式), 但我怀疑您的命令从未分配给(您正在使用自动属性) 我通常这样做:

      private ViewModelCommand viewOrganizationCommand;
      
      public ViewModelCommand ViewOrganizationCommand 
            {
               get
               {
                  if (viewOrganizationCommand  == null)
                     viewOrganizationCommand = new ViewModelCommand(Action, CanDoIt);
                  return viewOrganizationCommand;
               }
            }
      

      【讨论】:

        【解决方案4】:

        尝试将Button 的DataContext 设置为StackPanel 并设置Button 的Command 和CommandParameter。

        <datagrid:DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal" 
                                VerticalAlignment="Center" DataContext="{StaticResource XDataContext}">
                    <Button x:Name="button" Content="View" Margin="5" Command="{Binding ViewOrganizationCommand}" CommandParameter="{Binding ElementName=dtgOrganizations, Path=SelectedItem}" >
                    </Button>
                </StackPanel>
            </DataTemplate>
        </datagrid:DataGridTemplateColumn.CellTemplate>
        

        【讨论】:

          【解决方案5】:

          我通过在MVVMLight Toolkit 中使用 EventToCommand 行为解决了这个问题

          【讨论】:

            【解决方案6】:

            DataGrid 的每一行都将其 DataContext 设置为该对象。如果网格的 ItemSource 是 ObservableCollection,则每一行的 DataContext 都是 Organization 对象。

            有两种方法可以解决这个问题。

            1. 创建公开命令的包装或扩展 ViewModel。然后命令应该触发。这是一些伪代码。

              public class OrganizationExtensionViewModel
              {
                  <summary>
                  /// Private currentOrginization property.
                  /// </summary>          
                  private Organization currentOrginization;
              
                  public Organization CurrentOrganization
                  {
                      get
                      {
                          return this.currentOrginization;
                      }
              
                      set
                      {
                          if (this.currentOrginization != value)
                          {
                              this.currentOrginization = value;
                              this.RaisePropertyChanged("CurrentOrganization");
                          }
                      }
                  }
              
                  public ViewModelCommand ViewOrganizationCommand { get; set; }
                  public OrganizationExtensionViewModel(Organization o)
                  {
                      this.CurrentOrganization = o;
                      this.ViewOrganizationCommand = new ViewModelCommand(this.ViewOrgnaizationClicked);
                  }
              }
              
            2. 将 xaml 中的 ViewModel 定义为 StaticResource,并将其称为绑定路径。

            ... 在网格中

            <Button x:Name="button" Content="View" Margin="5" Command="{Binding ViewOrganizationCommand, Source={StaticResource viewModel}}" />
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2023-03-20
              • 2016-10-01
              相关资源
              最近更新 更多