【问题标题】:binding a command to a list将命令绑定到列表
【发布时间】:2010-12-05 04:20:35
【问题描述】:

我有相同的命令,我想对对话框类型窗口上的两个控件使用。作为可能有趣的背景,我正在使用 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 中的视觉效果,还是有更好的方法来做到这一点?

干杯,谢谢!
浆果

【问题讨论】:

    标签: wpf data-binding viewmodel


    【解决方案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>
    

    这里有更多关于Attached Behavior pattern的信息

    【讨论】:

    • 嗨,帕维尔。我现在无法理解所有这些,但它可以重复使用吗?如果没有,看起来像一个相当多的设置。乔什·史密斯(Josh Smith)也再次出现——看起来这个人是一个可以坚持一段时间的好人。当然有很多材料在那里。谢谢!
    • Berryl,是的,它当然是可重复使用的。您可以在任何 FrameworkElement 上设置此行为并将命令附加到它。例如,您可以创建一个图像元素并将双击行为附加到它。 。现在只要双击图像,PickImageCommand 就会执行。或者,您也可以使用相同的方式添加命令参数。
    • 嗨,帕维尔。你能看看我对你(工作)想法和评论的实施吗?谢谢!
    • Berryl,我很高兴听到它对你有用。您可以直接在列表视图上设置附加命令。 它应该可以正常工作。如果您有多个 ListView 想要使用相同的属性但您不必这样做,它有助于将其置于一种样式中。希望对您有所帮助!
    猜你喜欢
    • 2016-01-02
    • 1970-01-01
    • 2011-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多