1

だから私は一日中これで頭を壁にぶつけていました。

私の WPF アプリケーション (MVVM Light を使用) には、ビューモデルのコレクションにバインドされたコンテキスト メニューがあり、正しく動作していません。メニューを作成でき、MenuItems のツリーの動作、コマンドの実行、および適切なパラメーターの通過ですべてが完全に機能します。これを使用して、ユーザーがアイテムをフォルダーに追加できるコンテキスト メニューを作成しています。

私が遭遇した問題は、コンテキスト メニュー項目に子がある場合、コマンドが起動されなくなることです。したがって、子フォルダーを持たないフォルダーにのみアイテムを追加できます。

Snoop を使用してこれを調査したところ、MenuItem に対して DataContext が正しく表示され、コマンドが正しくバインドされ、mousedown イベントが発生します。

私が抱えている問題は、MenuItem に子がある場合、コマンドが実行されないことです。子を持たないアイテムの場合、コマンドは問題なく実行されます。

私はここで本当に途方に暮れており、スタック オーバーフローや MSDN ソーシャルに関する同様の質問はすべて未回答のままです。

バインディングをスタイルに設定しました。

<utility:DataContextSpy x:Key="Spy" />

<!-- Context style (in UserControl.Resources) -->

<Style x:Key="ContextMenuItemStyle" TargetType="{x:Type MenuItem}">
    <Setter Property="Header" Value="{Binding Header}"/>
    <Setter Property="ItemsSource" Value="{Binding Children}"/>
    <Setter Property="Command" Value="{Binding Command}" />
    <Setter Property="CommandParameter" Value="{Binding DataContext, Source={StaticResource Spy}" />
    <Setter Property="CommandTarget" Value="{Binding Path=PlacementTarget, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
</Style>

<!-- Later in the control -->
<ContextMenu ItemContainerStyle="{StaticResource ContextMenuItemStyle}" ItemsSource="{Binding MenuItems}" />

DataSpy はこの記事からのものであり、説明どおりに機能して、usedcontrol のデータコンテキストをコマンド パラメーターとして使用できることに注意してください。

http://www.codeproject.com/Articles/27432/Artificial-Inheritance-Contexts-in-WPF

コンテキストメニューに使用されるビューモデルは次のとおりです

public interface IContextMenuItem
{
    string Header { get; }
    IEnumerable<IContextMenuItem> Children { get; }
    ICommand Command { get; set; }
}

public class BasicContextMenuItem : ViewModelBase, IContextMenuItem
{
    #region Declarations

    private string _header;
    private IEnumerable<IContextMenuItem> _children;

    #endregion

    #region Constructor

    public BasicContextMenuItem(string header)
    {
        Header = header;
        Children = new List<IContextMenuItem>();
    }

    #endregion

    #region Observables

    public string Header
    {
        get { return _header; }
        set
        {
            _header = value;
            RaisePropertyChanged("Header");
        }
    }

    public IEnumerable<IContextMenuItem> Children
    {
        get { return _children; }
        set
        {
            _children = value;
            RaisePropertyChanged("Children");
        }
    }

    public ICommand Command { get; set; }

    #endregion
}

コンテキスト アイテムを実際に使用する方法を次に示します。

MenuItems = new List<IContextMenuItem>
{
    new BasicContextMenuItem("New Folder") { Command = NewFolderCommand} ,
    new BasicContextMenuItem("Delete Folder") { Command = DeleteFolderCommand },
    new BasicContextMenuItem("Rename") { Command = RenameFolderCommand },
};

public ICommand NewFolderCommand
{
    get { return new RelayCommand<FolderViewModel>(NewFolder); }
}

private void NewFolder(FolderViewModel viewModel)
{
    // Do work
}
4

1 に答える 1

0

問題は XAML バインディングにあるようです。必要なのはHierarchicalDataTemplate束縛です。このコードは、問題を引き起こしていると思われる子のコマンドをバインドしません。

これが役立つかどうかを確認してください-動的MVVMコンテキストメニューでコマンドバインディングが機能しない

于 2013-10-24T06:10:01.470 に答える