【问题标题】:Is it possible to invoke Command not from Button?是否可以不从按钮调用命令?
【发布时间】:2016-06-13 17:12:03
【问题描述】:

我有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}}"

【问题讨论】:

  • 是的,使用 Blend SDK 中的行为。 here is an example
  • .. 好像这是你今天的第四个问题 :)
  • @Gopichandar 是的!这真的很有趣! :)

标签: c# wpf mvvm command datatemplate


【解决方案1】:

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

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

路由事件触发器

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

自定义命令操作

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

【讨论】:

  • 只是补充一下,还有一种简单的方法可以做到这一点:&lt;ListBox ...&gt; &lt;i:Interaction.Triggers&gt; &lt;i:EventTrigger EventName="SelectionChanged"&gt; &lt;i:InvokeCommandAction Command="{Binding SelectedItemChangedCommand}"/&gt; &lt;/i:EventTrigger&gt; &lt;/i:Interaction.Triggers&gt; &lt;/ListBox&gt;
猜你喜欢
  • 2010-12-19
  • 1970-01-01
  • 2023-02-21
  • 1970-01-01
  • 2022-08-11
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多