开发者

How to fire event from button inside datagrid in silverlight and MVVM

I have button at first column in datagrid. I am using MVVM and try to bind Command to Command in ViewModel but when I click button in each row, it don't work (It don't call Command in ViewModel) but if I move that button out of datagrid it's working properly.

How can I fire event from button inside datagrid in MVVM?

Update 1:

XAML's code is:

<datagrid:DataGridT开发者_如何学运维emplateColumn.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's code is:

public ViewModelCommand ViewOrganizationCommand { get; set; }


Instead of using EventTrigger, why not simply bind to Button.Command directly, like so?

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

That will bind the command, and set the CommandParameter to the DataContext of the Button, which presumably is a good thing to bind the parameter to. If it's not, just bind CommandParameter to something else that helps you uniquely identify the specific row being clicked on.


This article brings the solution with DataContextProxy. Applying this solution makes possible to write a button code like Austin Lamb's answer.


The command binding using the Event Trigger looks fine (This is how i always do it), But I suspect that your command is never assigned to (You are using Automatic Properties) I usually do it like this:

private ViewModelCommand viewOrganizationCommand;

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


try setting you Button's DataContext to the StackPanel and set the Command and CommandParameter of the Button.

<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>


I solved this problem by use EventToCommand behavior in MVVMLight Toolkit


Each row of the DataGrid has it's DataContext set to that object. If the ItemSource for the grid is an ObservableCollection, each row's DataContext is the Organization object.

There are two ways to handle this.

  1. Create a wrapping or extension ViewModel that exposes the command. Then the command should fire.Here is some psuedo code.

    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. Define the ViewModel in the xaml as a StaticResource and refer to it as the binding path.

... In the grid

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜