20

コンテキストメニューがあります。これはいくつかのコレクションにバインドされており、次のように定義されたItemTemplateがあります。

<ContextMenu
    ItemsSource={Binding ...}
    ItemTemplate={StaticResource itemTemplate}
    />

itemTemplateは、TextBlockを備えた単純なDataTemplateです。

<DataTemplate x:Key="itemTemplate">
    <TextBlock Text={Binding ...} />
</DataTemplate>

MenuItemのCommandプロパティを基になるオブジェクトのプロパティにバインドするにはどうすればよいですか?

4

3 に答える 3

25

TextBlockをMenuItemでラップする必要があると思います。

<DataTemplate x:Key="itemTemplate">
    <MenuItem Command={Binding ...}>
        <TextBlock Text={Binding ...} />
    </MenuItem>
</DataTemplate>

しかし、私は今、これを試すためのIDEを目の前に持っていません。どうなるか教えてください。


ここに示すように、ItemContainerStyleを使用する必要があるようです。最初に間違った道を案内して申し訳ありませんが、IDEの前に来て、これは機能します:

<ContextMenu.ItemContainerStyle>
    <Style TargetType="MenuItem">
        <Setter Property="Command" Value="{Binding ...}"/>
    </Style>
</ContextMenu.ItemContainerStyle>
于 2009-05-22T16:56:38.727 に答える
6

これはマーティン・ハリスの答えのほんのわずかなバリエーションですが、とにかくそれを共有したいと思いました。コレクション全体に対して単一のコマンドを指定し、CommandParameterを送信する方が便利であることがわかりました。

<MenuItem.ItemContainerStyle>
    <Style TargetType="MenuItem">
       <Setter Property="Command" Value="{x:Static v:ViewModel.CommandForAll}"/>
       <Setter Property="CommandParameter" Value="{Binding ValueForCommand}"/>
    </Style>
</MenuItem.ItemContainerStyle>

次に、コマンドのハンドラーで何をするかを決定できます。

private void CommandForAll_Executed(object sender, ExecutedRoutedEventArgs e)
{
    var cmdParam = e.Paramater as ExpectedType
    if (cmdParam != null)
        //DoStuff...
}
于 2012-05-04T19:33:41.867 に答える
0

事後にかなり答えていることに気づきましたが、同じ問題に遭遇し、以前の答えは複数の異なるコマンドへのバインドを困難にしているように見えました。私が到達したソリューションは、MatrixManAtYrServiceのソリューションと非常によく似ており、次の3つの部分で機能します。

1)ItemContainerStyleプロパティを使用してコマンドをViewModelのコマンドにバインドします。これは、前の回答と同じです。1つの例外は、CommandParameterをMenuItemにバインドすることです。

<Setter Property="CommandParameter" Value="{Binding RelativeSource={RelativeSource Self}}"/>

2)カスタムクラスを作成して、各MenuItemの外観と動作を定義します。メニューのItemsSourceは、これらのリストに設定されます。これは他の答えと同じです。ただし、私の実装では、MenuItemCommandが呼び出されたときに実行されるアクションをクラスに指定しました。MenuItemを無効にできるブール値も含めました。

public class MenuAction
{
    public string Name { get => name; set => name = value; }
    public Action Action { get => action; set => action = value; }
    public bool CanExecute { get => canExecute; set => canExecute = value; }
}

3)コマンド実装で、MenuActionのデリゲートへのルート制御。

public void HandleCommand(object sender)
{
    MenuItem clickedMenuItem = sender as MenuItem;
    MenuAction menuAction = clickedMenuItem?.DataContext as MenuAction;
    if(menuAction != null)
        menuAction.Action();
}

public bool CanMenuItemExecute(object sender)
{
    MenuItem clickedMenuItem = sender as MenuItem;
    MenuAction menuAction = clickedMenuItem?.DataContext as MenuAction;
    if (menuAction != null)
        return menuAction.CanExecute;
    else
        return false;
}

これにより、コマンドのすべての動作をリストで定義できるようになります。技術的には単一のコマンドにバインドされていますが、機能的には複数の異なるコマンドを持つことに似ています。同じメソッドは、ネストされたMenuItemsとHierarchicalDataTemplatesでも、多少の調整を加えて機能するはずです。

于 2019-12-03T07:30:29.263 に答える