c# - 是否可以从Button调用Command?

标签 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}}"时,是否可能?

最佳答案

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

        <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);
                    }
                }
            }
        }
    }
}

关于c# - 是否可以从Button调用Command?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35720297/

相关文章:

c# - 在另一个 Web API 中管理 Web API JWT token 的最佳实践

c# - 将 PowerPoint 查看器包含到我的 WPF 应用程序中

wpf - 如何在 WPF 数据网格上启用滚动条/滚动

c# - map 初始化后将标记添加到谷歌地图

c# - 如何在按钮单击事件期间在对象列表中保留和添加项目

c# - 通过标记扩展注入(inject)命令是一种好习惯吗?

c#有没有类似于多变量声明的参数构造?

c# - 使用 MVVM 实现可变网格行数

MVVM 用户控件 - 我在哪里声明它以从页面获取数据?

c# - ViewModel 中的 MediaElement.play()