0

我有相同的命令,我想用于对话框类型窗口上的两个控件。作为可能有趣的背景,我正在使用 Josh Smith 的 ViewModel / RelayCommand 想法,因为我是 WPF 新手,这是我看到的第一件事,我可以从大局的角度真正理解。

所以命令是 ViewModel 的一个属性,并且在 Button 的内置支持下,在 XAML 中绑定到命令是微不足道的和轻松的:

<Button ... Command="{Binding Path=PickCommand}"  Content="_Ok"></Button>

现在在 ListView 中,我使用连接到双击触发的相同命令的唯一方法是使用事件处理程序:

<ListView ...
              ItemsSource="{Binding Path=AvailableProjects}" 
              SelectedItem="{Binding Path=SelectedProject, Mode=TwoWay}"
              MouseDoubleClick="OnProjectListingMouseDoubleClick"
              >

private void OnProjectListingMouseDoubleClick(object sender, MouseButtonEventArgs e) {
        var vm = (ProjectSelectionViewModel) DataContext;
        vm.Pick(); // execute the pick command
    }

有没有办法通过绑定按钮的方式来做到这一点?

干杯,
贝里尔

<------- 实施 - 有没有更好的方法?--->

您的 SelctionBehavior 类是正确的,但我对您的 xaml 代码感到困惑。通过在 listViewItem 上设置“样式”,我得到了要执行的命令所在的 DataContext 的子级。所以我将行为附加到 ListView 本身:

<ListView ...Style="{StaticResource _attachedPickCommand}" >

并将样式放入资源字典中:

<Style x:Key="_attachedPickCommand" TargetType="ListView">
    <Setter Property="behaviors:SelectionBehavior.DoubleClickCommand" Value="{Binding Path=PickCommand}" />
</Style>

有用!但是设置列表视图的样式属性“感觉”很尴尬。这仅仅是因为我不喜欢风格而不是 wpf 中的视觉效果,还是有更好的方法来做到这一点?

干杯,谢谢!
绿柱石

4

1 回答 1

1

就在这里!您可以使用附加行为并将命令绑​​定到该行为。

  public class SelectionBehavior {
public static readonly DependencyProperty CommandParameterProperty=
  DependencyProperty.RegisterAttached("CommandParameter", typeof(object), typeof(SelectionBehavior));

public static readonly DependencyProperty DoubleClickCommandProperty=
  DependencyProperty.RegisterAttached("DoubleClickCommand", typeof(ICommand), typeof(SelectionBehavior),
                                      new PropertyMetadata(OnDoubleClickAttached));

private static void OnDoubleClickAttached(DependencyObject d, DependencyPropertyChangedEventArgs e) {
  var fe=(FrameworkElement)d;

  if(e.NewValue!=null && e.OldValue==null) {
    fe.PreviewMouseDown+=fe_MouseDown;
  } else if(e.NewValue==null && e.OldValue!=null) {
    fe.PreviewMouseDown-=fe_MouseDown;
  }
}

private static void fe_MouseDown(object sender, MouseButtonEventArgs e) {
  if(e.ClickCount==2) {
    var dep=(FrameworkElement)sender;

    var command=GetDoubleClickCommand(dep);

    if(command!=null) {
      var param=GetCommandParameter(dep);
      command.Execute(param);
    }
  }
}

public static ICommand GetDoubleClickCommand(FrameworkElement element) {
  return (ICommand)element.GetValue(DoubleClickCommandProperty);
}

public static void SetDoubleClickCommand(FrameworkElement element, ICommand value) {
  element.SetValue(DoubleClickCommandProperty, value);
}

public static object GetCommandParameter(DependencyObject element) {
  return element.GetValue(CommandParameterProperty);
}

public static void SetCommandParameter(DependencyObject element, object value) {
  element.SetValue(CommandParameterProperty, value);
}

}

在 xaml 中,您需要为 ListViewItem 设置一个样式,该样式代表您在 ListView 中的数据。例子

        <ListView>
        <ListView.ItemContainerStyle>
            <Style TargetType="{x:Type ListViewItem}">
                <Setter Property="local:SelectionBehavior.DoubleClickCommand" Value="{Binding Path=DataContext.PickCommand}"/>
                <Setter Property="local:SelectionBehavior.CommandParameter" Value="{Binding Path=DataContext}"/>
            </Style>
        </ListView.ItemContainerStyle>
    </ListView>

这是有关附加行为模式的更多信息

于 2009-10-08T22:54:25.590 回答