2012-12-24 80 views
18

我有listview,當有人在任何位置雙擊時我想要顯示新窗口。但我有mvvm應用程序,並且我不想在xaml文件後面的代碼中具有任何功能,如下所示:How to bind a Command to double-click on a row in DataGrid以及其他許多示例。我想在視圖模型文件的方法,並將其綁定這樣的:如何在mvvm中綁定moused double click命令

<ListView ... MouseDoubleClick="{Binding myfunction}"> 

感謝

+0

看看[這裏](http://stackoverflow.com/questions/4785685/wpf-and-mvvm-binding -events)爲Mouse事件的MVVM示例。 –

回答

22

這是一個基於列表中單擊項目觸發命令(在ViewModel中)的方法的工作示例。 ViewModel中的命令將獲得「clicked」項目作爲其參數。

我使用的Textblock.InputBindings和可能是由Blachshma鏈接的混合SDK的一部分,但你不會需要任何其他DLL這個工作。

在我的例子視圖模型綁定到用戶控件的DataContext的,這就是爲什麼我需要使用的RelativeSource FindAncestor從我的TextBlock找到視圖模型。

編輯: 通過結合寬度的TextBlock列表框ActualWidth的固定寬度的問題。

只是一個問題,雙擊將只有當你點擊的文本塊內的文本,即使該列表本身更廣泛的合作。

<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> 
+0

謝謝@Peter –

9

要做到這一點是使用System.Windows.InteractivityMicrosoft.Expression.Interactions(均爲自由可通過Blend SDK

最簡單的方法因此,通過添加下面的命名空間,以你的觀點

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" 

下一頁開始,趕上DoubleClick事件和PA它SS到命令:

<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所述一個,並可以下載here。 它一旦觸發事件就執行命令(myFunction)。

這是基於myFunction命令是在ListView用戶的DataContext中的假設。否則,將EventToCommand的綁定修改爲命令所在的位置。

+0

我添加了對Microsoft.Expression.Interactions.dll的引用,現在構建中有一個錯誤,說這個dll在WPF項目中不受支持。 VS 2013. – Rhyous

+0

如何找到可用的有效事件名稱,例如EventName =「MouseDoubleClick」?因爲它不提供智能感知。 –

+0

這應該被標記爲答案。 – Jeb

14

您可以使用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 ....}"/>