19

リストビューがあり、誰かが任意の位置でダブルクリックしたときに新しいウィンドウを表示したい。しかし、私は mvvm アプリケーションを持っていて、xaml ファイルの背後にあるコードに次のような機能を持ちたくありません: DataGrid の行をダブルクリックするコマンドをバインドする方法と、このような他の多くのサンプル。ビューモデルファイルにメソッドを持ち、次のようにバインドしたい:

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

ありがとう

4

3 に答える 3

24

これは、リスト内のクリックされた項目に基づいて (ViewModel 内で) コマンドをトリガーするメソッドの実例です。ViewModel のコマンドは、「クリックされた」項目をパラメーターとして取得します。

私は Textblock.InputBindings を使用しています。これは Blachshma によってリンクされたBlend SDKの一部である可能性がありますが、これを機能させるために他の DLL は必要ありません。

私の例では、ViewModel は UserControl の DataContext にバインドされているため、RelativeSource FindAncestorを使用して TextBlock から ViewModel を見つける必要があります。

編集: TextBlockのWidthListBoxActualWidthにバインドして、幅の問題を修正しました。

1 つだけ問題があります。ダブルクリックは、リスト自体がはるかに広い場合でも、テキストブロック内のテキスト内をクリックした場合にのみ機能します。

    <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>
于 2012-12-24T22:55:24.937 に答える
17

添付プロパティを使用して、必要なイベントをバインドできます。

の場合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 ....}"/>
于 2012-12-25T06:18:43.863 に答える
12

これを行う最も簡単な方法は、 と を使用することSystem.Windows.Interactivityです(どちらもBlend SDKMicrosoft.Expression.Interactionsから無料で入手できます) 。

したがって、次の名前空間をビューに追加することから始めます

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これは、コマンドが ListView が使用する DataContext にあるという前提に基づいています。それ以外の場合は、EventToCommand のバインドを、コマンドがある場所に変更します。

于 2012-12-24T20:56:04.823 に答える