C# 如何在mvvm中绑定鼠标双击命令
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14025530/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to bind mousedouble click command in mvvm
提问by Robert
I have listview and I want to have show new window when someone double click in any position. But I have mvvm application and I don't want to have any function in code behind of xaml file, like this: How to bind a Command to double-click on a row in DataGridand many other samples like this. I want to have method in viewmodel file and bind it like this:
我有列表视图,我想在有人双击任何位置时显示新窗口。但是我有 mvvm 应用程序,我不想在 xaml 文件的代码后面有任何功能,就像这样:如何绑定命令以双击 DataGrid 中的一行以及许多其他类似的示例。我想在 viewmodel 文件中有方法并像这样绑定它:
<ListView ... MouseDoubleClick="{Binding myfunction}">
Thanks
谢谢
采纳答案by Peter Henell
This is a working example of a method to trigger a command (In the ViewModel) based on the clicked item in a list. The command in the ViewModel will get the "clicked" item as its parameter.
这是基于列表中单击的项目触发命令(在 ViewModel 中)的方法的工作示例。ViewModel 中的命令将获得“clicked”项作为其参数。
I'm using the Textblock.InputBindings and that might be part of the Blend SDKlinked by Blachshma, but you will not need any other DLLs for this to work.
我正在使用 Textblock.InputBindings,它可能是由 Blachshma 链接的Blend SDK的一部分,但您不需要任何其他 DLL 即可使其工作。
In my example the ViewModel is bound to the DataContext of the UserControl, that is why I need to use the RelativeSource FindAncestorto find the ViewModel from my TextBlock.
在我的示例中,ViewModel 绑定到 UserControl 的 DataContext,这就是为什么我需要使用RelativeSource FindAncestor从我的 TextBlock 中查找 ViewModel。
Edit: Fixed the width problem by binding the Widthof the TextBlockto the ActualWidthof the ListBox.
编辑:通过结合固定宽度问题宽度的的的TextBlock到ActualWidth的所述的列表框。
Just oneproblem, the double click will only work when you click inside the text in the textblock even if the list itself is much wider.
只是一个问题,即使列表本身更宽,双击也仅在您在文本块中的文本内部单击时才起作用。
<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>
回答by Blachshma
The easiest way to do this is to use System.Windows.Interactivity
and Microsoft.Expression.Interactions
(both freely available through the Blend SDK)
最简单的方法是使用System.Windows.Interactivity
和Microsoft.Expression.Interactions
(都可以通过Blend SDK免费获得)
So start by adding the following namespaces to your view
因此,首先将以下命名空间添加到您的视图中
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
Next, catch the DoubleClick event and pass it to the command:
接下来,捕获 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>
Note: The EventToCommand
used is the one from the MVVM Light Toolkitand can be downloaded here.
What it does is execute the command (myFunction
) as soon as the event is triggered.
注意:EventToCommand
使用的是MVVM Light Toolkit 中的一个,可以在这里下载。它的作用是myFunction
在事件触发后立即执行命令 ( )。
This is based on the assumption that the myFunction
command is in the DataContext which the ListView users. Otherwise, modify the binding of the EventToCommand to wherever the command is.
这是基于myFunction
命令位于 ListView 用户的 DataContext 中的假设。否则,将 EventToCommand 的绑定修改为命令所在的位置。
回答by Gypsy
You can use Attached Propertiesto bind any event you want.
您可以使用附加属性来绑定您想要的任何事件。
For MouseDoubleClick
:
对于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);
}
}
}
And in Xaml:
在 Xaml 中:
<ListBox Behavior:MouseDoubleClick.Command="{Binding ....}"
Behavior:MouseDoubleClick.CommandParameter="{Binding ....}"/>