如何在Silverlight和MVVM中从DataGrid内部的按钮触发事件

5

我在数据网格的第一列有一个按钮。我正在使用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 代码会很有帮助。请添加它。 - P.K
源代码按照你的建议添加 :) - Anonymous
1
你有收到任何绑定异常吗?你可以在输出窗口中看到它。 - thomasmartinsen
6个回答

1

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

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

这将绑定命令,并将CommandParameter设置为按钮的DataContext,这可能是将参数绑定到的好方法。如果不是,请将CommandParameter绑定到其他有助于唯一标识单击的特定行的内容。


1

这篇文章介绍了使用DataContextProxy的解决方案。应用此解决方案可以编写像Austin Lamb的答案一样的按钮代码。


0

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

处理这种情况有两种方法。

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

    public class OrganizationExtensionViewModel
    {
        <summary>
        /// 私有的currentOrginization属性。
        /// </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}}" />

0

使用事件触发器进行命令绑定看起来很好(这是我经常使用的方法), 但我怀疑你的命令从未被分配(你正在使用自动属性) 我通常会这样做:

private ViewModelCommand viewOrganizationCommand;

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

0
尝试将您的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>

0

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接