MvvmLight的EventToCommand和WPFToolkit的DataGrid双击事件

5

试图弄清楚如何使用EventToCommand为行设置datagrid双击处理程序。该命令位于每行的视图模型中。这就是我的经验,因为我尚未使用过交互。

谢谢。

我本来会使用mvvmlight标签,但我还没有足够的声望来创建新标签。


我已经为您添加了mvvm-light标签。这是Laurent Bugnion的MVVM Light工具包官方使用的标签。 - dthrasher
2个回答

11

如果Command存放在“GridViewModel”而不是“RowViewModel”上,那么这将是解决方案。

    <Window...    
         ...xmlns:dg="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit" 
            xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
            xmlns:GalaSoft_MvvmLight_Command="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras">
         <dg:DataGrid x:Name="dg">
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="MouseDoubleClick">
                            <GalaSoft_MvvmLight_Command:EventToCommand CommandParameter="{Binding SelectedItem, ElementName=dg}" Command="{Binding Path=SelectCommand, Mode=OneWay}"/>
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
            </dg:DataGrid>
    </Window>

您可以创建一个RowView,因为行也有自己的ViewModel,并使用行视图中子元素(容器)的mousedoubleclick事件。

或者,您可以为命令绑定创建转换器:

<GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding SelectedItem, ElementName=dg, Mode=OneWay, Converter=...}"/>
转换器随后将检查 selectedItem 是否符合所需类型以返回命令(类似于具有 RelayCommand 属性的 ISelectCommandable)。

撕心裂肺...我很长一段时间都没有机会尝试这个,但是不想让它无人问津。理论上看起来没问题,但我真的希望有一个命令在RowViewModel上。<dg:DataGrid x:Name="dg" Items="RowVMCollection">或者你是在暗示DataGrid没有提供双击支持以识别所涉及的行? - Thomas
转换器背后的想法是,转换器将SelectedItem强制转换并返回Command。这样,您将在RowViewModel上调用命令(我不确定您是否需要它或者是否可以执行类似于SelectedItem.SelectCommand的操作)。 要识别行是否已双击,您需要使用EventArgs。但是,您也可以使用mvvm-light工具包返回它。 - CodeWeasel
谢谢提供示例语法。如果我有时间尝试这种方法,我会再次回复您的。 - Thomas

4

如果有人来到这里并想知道我是如何在没有使用EventToCommand的情况下完成它的

public class DataGridAttachedBehaviors
{
   #region DoubleClick

   public static DependencyProperty OnDoubleClickProperty = DependencyProperty.RegisterAttached(
       "OnDoubleClick",
       typeof(ICommand),
       typeof(DataGridAttachedBehaviors),
       new UIPropertyMetadata(DataGridAttachedBehaviors.OnDoubleClick));

   public static void SetOnDoubleClick(DependencyObject target, ICommand value)
   {
      target.SetValue(DataGridAttachedBehaviors.OnDoubleClickProperty, value);
   }

   private static void OnDoubleClick(DependencyObject target, DependencyPropertyChangedEventArgs e)
   {
      var element = target as Control;
      if (element == null)
      {
         throw new InvalidOperationException("This behavior can be attached to a Control item only.");
      }

      if ((e.NewValue != null) && (e.OldValue == null))
      {
         element.MouseDoubleClick += MouseDoubleClick;
      }
      else if ((e.NewValue == null) && (e.OldValue != null))
      {
         element.MouseDoubleClick -= MouseDoubleClick;
      }
   }

   private static void MouseDoubleClick(object sender, MouseButtonEventArgs e)
   {
      UIElement element = (UIElement)sender;
      ICommand command = (ICommand)element.GetValue(DataGridAttachedBehaviors.OnDoubleClickProperty);
      command.Execute(null);
   }

   #endregion DoubleClick

  #region SelectionChanged
  //removed
  #endregion
}

在我的xaml文件中:

<dg:DataGrid.RowStyle>
   <Style BasedOn="{StaticResource DataGridDemoRowStyle}"           
          TargetType="{x:Type dg:DataGridRow}">
       <Setter Property="skins:DataGridAttachedBehaviors.OnDoubleClick"
               Value="{Binding Recall}" />
   </Style>
</dg:DataGrid.RowStyle>

刚看到这个,没有花太多时间详细查看:你实际上只是在这里实现了一个EventToCommand Light,是吗? - carlsb3rg
不知道我是否可以这样称呼它,因为这非常特定于双击,但没关系。 - Thomas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接