是否可以从Button调用Command?

时间:2016-03-01 10:21:45

标签: c# wpf mvvm command datatemplate

DataGridDataTemplate

<DataGrid ItemsSource="{Binding Persons}" Grid.Row="1" AutoGenerateColumns="False"> 
  <DataGrid.Columns>
    <DataGridTextColumn Binding="{Binding IdPerson}">                    
       <DataGridTextColumn.HeaderTemplate>                        
          <DataTemplate>
             <Grid>
                <Grid.RowDefinitions>
                   <RowDefinition/>
                   <RowDefinition/>
                   <RowDefinition/>
                </Grid.RowDefinitions>
               <Button DataContext="{Binding Path=Data, Source={StaticResource proxy}}" 
Command="{Binding DataContext.HelloCommand, RelativeSource={RelativeSource  
AncestorType=Window}}"/>
               <TextBlock Grid.Row="1" HorizontalAlignment="Center" Text = "{Binding 
DataContext.Hello, RelativeSource={RelativeSource AncestorType=DataGrid}}"/>                                                   
            </Grid>                            
         </DataTemplate>
      </DataGridTextColumn.HeaderTemplate>                   
   </DataGridTextColumn>
   <DataGridTextColumn Header="FirstName" Binding="{Binding FirstName}"/>
   <DataGridTextColumn Header="LastName" Binding="{Binding LastName}"/>
   </DataGrid.Columns>
</DataGrid>  

当用户点击DataTemplate的任何地方(HeaderTemplate范围)来调用Button的Command="{Binding DataContext.HelloCommand, RelativeSource={RelativeSource AncestorType=Window}}"时,是否可以点击?

1 个答案:

答案 0 :(得分:2)

基本思路是为此使用附加的路由事件。以下是此代码段:

        <i:Interaction.Triggers>
            <local:RoutedEventTrigger RoutedEvent="Mouse.MouseDown">
                <local:CustomCommandAction Command="{Binding DataContext.HelloCommand, RelativeSource={RelativeSource AncestorType=Window}}" />
            </local:RoutedEventTrigger>
        </i:Interaction.Triggers>

RoutedEventTrigger

public class RoutedEventTrigger : EventTriggerBase<DependencyObject>
{
    RoutedEvent _routedEvent;

    public RoutedEvent RoutedEvent
    {
        get { return _routedEvent; }
        set { _routedEvent = value; }
    }

    public RoutedEventTrigger()
    {
    }
    protected override void OnAttached()
    {
        Behavior behavior = base.AssociatedObject as Behavior;
        FrameworkElement associatedElement = base.AssociatedObject as FrameworkElement;

        if (behavior != null)
        {
            associatedElement = ((IAttachedObject)behavior).AssociatedObject as FrameworkElement;
        }
        if (associatedElement == null)
        {
            throw new ArgumentException("Routed Event trigger can only be associated to framework elements");
        }
        if (RoutedEvent != null)
        {
            associatedElement.AddHandler(RoutedEvent, new RoutedEventHandler(this.OnRoutedEvent));
        }
    }
    void OnRoutedEvent(object sender, RoutedEventArgs args)
    {
        base.OnEvent(args);
    }
    protected override string GetEventName()
    {
        return RoutedEvent.Name;
    }
}

CustomCommandAction

public sealed class CustomCommandAction : TriggerAction<DependencyObject>
{
    public static readonly DependencyProperty CommandParameterProperty =
        DependencyProperty.Register("CommandParameter", typeof(object), typeof(CustomCommandAction), null);

    public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
        "Command", typeof(ICommand), typeof(CustomCommandAction), null);

    public ICommand Command
    {
        get
        {
            return (ICommand)this.GetValue(CommandProperty);
        }
        set
        {
            this.SetValue(CommandProperty, value);
        }
    }

    public object CommandParameter
    {
        get
        {
            return this.GetValue(CommandParameterProperty);
        }

        set
        {
            this.SetValue(CommandParameterProperty, value);
        }
    }

    protected override void Invoke(object parameter)
    {
        if (this.AssociatedObject != null)
        {
            ICommand command = this.Command;
            if (command != null)
            {
                if (this.CommandParameter != null)
                {
                    if (command.CanExecute(this.CommandParameter))
                    {
                        command.Execute(this.CommandParameter);
                    }
                }
                else
                {
                    if (command.CanExecute(parameter))
                    {
                        command.Execute(parameter);
                    }
                }
            }
        }
    }
}