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 DataGrid and many other samples like this. I want to have method in viewmodel file and bind it like this:
<ListView ... MouseDoubleClick="{Binding myfunction}">
Thanks
MVVM – WPF Data Bindings For data binding you need to have a view or set of UI elements constructed, and then you need some other object that the bindings are going to point to. The UI elements in a view are bound to the properties which are exposed by the ViewModel.
What's a Command? Commands are an implementation of the ICommand interface that is part of the . NET Framework. This interface is used a lot in MVVM applications, but it is useful not only in XAML-based apps.
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.
I'm using the Textblock.InputBindings and that might be part of the Blend SDK linked by Blachshma, but you will not need any other DLLs for this to work.
In my example the ViewModel is bound to the DataContext of the UserControl, that is why I need to use the RelativeSource FindAncestor to find the ViewModel from my TextBlock.
Edit: Fixed the width problem by binding the Width of the TextBlock to the ActualWidth of the ListBox.
Just one problem, 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>
You can use Attached Properties to bind any event you want.
For 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:
<ListBox Behavior:MouseDoubleClick.Command="{Binding ....}"
Behavior:MouseDoubleClick.CommandParameter="{Binding ....}"/>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With