如何从silverlight和MVVM中的datagrid中的按钮触发事件

时间:2010-12-09 08:24:39

标签: silverlight mvvm

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

如何从MVVM中的datagrid中的按钮触发事件?

更新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; }

6 个答案:

答案 0 :(得分:1)

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

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

这将绑定命令,并将CommandParameter设置为Button的DataContext,这可能是将参数绑定到的好东西。如果不是,只需将CommandParameter绑定到其他可帮助您唯一标识所单击的特定行的其他内容。

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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

private ViewModelCommand viewOrganizationCommand;

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

答案 3 :(得分: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>

答案 4 :(得分:0)

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,并将其称为绑定路径。

            

  3. ... 在网格中

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

答案 5 :(得分:0)

我通过使用MVVMLight Toolkit

中的EventToCommand行为解决了这个问题