привязка команды к списку - PullRequest
       30

привязка команды к списку

0 голосов
/ 09 октября 2009

У меня та же команда, которую я хочу использовать для двух элементов управления в окне типа диалога. В качестве потенциально интересного фона я использую идеи Джоша Смита 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
    }

Есть ли способ сделать это, привязав способ, которым кнопка делает это?

Приветствия
Berryl

<------- реализация - есть ли лучший способ? --->

Ваш класс 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, или есть лучший способ сделать это?

Ура и спасибо!
Berryl

1 Ответ

1 голос
/ 09 октября 2009

Да, есть! Вы можете использовать прикрепленное поведение и привязать команду к этому поведению.

  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>

Вот еще немного информации о Прикрепленном образце поведения

...