Как связать команду mousedouble click в mvvm
У меня есть listview, и я хочу показать новое окно, когда кто-то дважды щелкнет в любой позиции. Но у меня есть приложение mvvm, и я не хочу иметь какую-либо функцию в коде позади файла xaml, например: Как связать команду для двойного щелчка по строке в DataGrid и многие другие подобные образцы. Я хочу иметь метод в файле viewmodel и связывать его следующим образом:
<ListView ... MouseDoubleClick="{Binding myfunction}">
Спасибо
Ответы
Ответ 1
Это рабочий пример метода для запуска команды (в ViewModel) на основе щелчка элемента в списке. Команда в ViewModel получит в качестве параметра параметр "clicked".
Я использую Textblock.InputBindings и может быть частью Blend SDK, связанным с Blachshma, но для этого вам не нужны никакие другие DLL.
В моем примере ViewModel привязан к DataContext UserControl, поэтому мне нужно использовать RelativeSource FindAncestor, чтобы найти ViewModel из моего TextBlock.
Edit:
Исправлена проблема с шириной, связывая ширину TextBlock с ActualWidth ListBox.
Просто одна проблема, двойной щелчок будет работать только при щелчке внутри текста в текстовом блоке, даже если сам список намного шире.
<ListView ItemsSource="{Binding Model.TablesView}" Grid.Row="1"
SelectedItem="{Binding Model.SelectedTable, Mode=TwoWay}" >
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=.}"
Width="{Binding Path=ActualWidth,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListView}}}" >
<TextBlock.InputBindings>
<MouseBinding MouseAction="LeftDoubleClick" Command="{Binding DataContext.MoveItemRightCommand,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type UserControl}}}"
CommandParameter="{Binding .}"/>
</TextBlock.InputBindings>
</TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Ответ 2
Вы можете использовать Attached Properties для привязки любого события, которое вы хотите.
Для MouseDoubleClick
:
namespace Behavior
{
public class MouseDoubleClick
{
public static DependencyProperty CommandProperty =
DependencyProperty.RegisterAttached("Command",
typeof(ICommand),
typeof(MouseDoubleClick),
new UIPropertyMetadata(CommandChanged));
public static DependencyProperty CommandParameterProperty =
DependencyProperty.RegisterAttached("CommandParameter",
typeof(object),
typeof(MouseDoubleClick),
new UIPropertyMetadata(null));
public static void SetCommand(DependencyObject target, ICommand value)
{
target.SetValue(CommandProperty, value);
}
public static void SetCommandParameter(DependencyObject target, object value)
{
target.SetValue(CommandParameterProperty, value);
}
public static object GetCommandParameter(DependencyObject target)
{
return target.GetValue(CommandParameterProperty);
}
private static void CommandChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
{
Control control = target as Control;
if (control != null)
{
if ((e.NewValue != null) && (e.OldValue == null))
{
control.MouseDoubleClick += OnMouseDoubleClick;
}
else if ((e.NewValue == null) && (e.OldValue != null))
{
control.MouseDoubleClick -= OnMouseDoubleClick;
}
}
}
private static void OnMouseDoubleClick(object sender, RoutedEventArgs e)
{
Control control = sender as Control;
ICommand command = (ICommand)control.GetValue(CommandProperty);
object commandParameter = control.GetValue(CommandParameterProperty);
command.Execute(commandParameter);
}
}
}
И в Xaml:
<ListBox Behavior:MouseDoubleClick.Command="{Binding ....}"
Behavior:MouseDoubleClick.CommandParameter="{Binding ....}"/>
Ответ 3
Самый простой способ сделать это - использовать System.Windows.Interactivity
и Microsoft.Expression.Interactions
(оба свободно доступны через Blend SDK)
Итак, начните с добавления следующих пространств имен в ваше представление
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
Затем перехватите событие DoubleClick и передайте его команде:
<ListView ..... >
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<local:EventToCommand Command="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DataContext.myfunction}" />
</i:EventTrigger
</i:Interaction.Triggers>
</ListView>
Примечание. Используемый EventToCommand
является одним из MVVM Light Toolkit и может быть загружен .
Он выполняет команду (myFunction
) сразу после запуска события.
Это основано на предположении, что команда myFunction
находится в DataContext, которую пользователи ListView. В противном случае измените привязку EventToCommand до любой команды.