2

ノード階層を持つ WPF ツリービューを持つアプリケーションがあります。選択した 1 つ以上のノードのコンテキスト メニューを表示する必要があります。1 つ以上のノードが選択されると、viewmodel のコレクションに、選択されたすべてのノードが取り込まれます。

ツリービュー コンテキスト メニューにバインドされたメニュー項目のコレクションがあります。ユーザーがノード(またはノード)を右クリックしたときにのみ、このバインディングが評価されるようにします。

ここでもう少し具体的に言うと、私が欲しいのは次のとおりです。

  • ユーザーが 1 つ以上のメニュー項目をクリックして選択する
  • 彼はコンテキストメニューを表示するために右クリックします。現在起こっているように、ユーザーが各メニューアイテムをクリックしている間ではなく、この時点でコンテキストメニュー入札 (MenuItems) を評価する必要があります。

以下は私のコードです:

<TreeView MinWidth="100" ItemsSource="{Binding Nodes}">
    <i:Interaction.Behaviors>
        <Behaviors1:BindableSelectedItemBehavior SelectedItem="{Binding SelectedItem, Mode=TwoWay}" />
    </i:Interaction.Behaviors>   
    <TreeView.ContextMenu>
        <ContextMenu ItemsSource="{Binding MenuItems}"  Visibility="{Binding ShowContextMenu, Converter={StaticResource VisibilityConverter}}">
            <ContextMenu.ItemContainerStyle>
                <Style TargetType="MenuItem">
                    <Setter Property="Header" Value="{Binding Name}"/>
                    <Setter Property="IsEnabled" Value="{Binding IsEnabled}"/>
                    <Setter Property="Command" Value="{Binding MenuCommand}"/>
                </Style>
            </ContextMenu.ItemContainerStyle>
        </ContextMenu>
    </TreeView.ContextMenu>
</TreeView>

そして私のViewModel:

internal class MyViewModel : NotificationObject
{
    private readonly IContextMenuProvider _contextMenuProvider;

    public MyViewModel(IContextMenuProvider contextMenuProvider)
    {
        _contextMenuProvider = contextMenuProvider;
    }

    public ObservableCollection<IMenuItem> MenuItems
    {
        get
        {
            System.Diagnostics.Debug.WriteLine("Getting menu items");
            return GetMenuItems();
        }
    }

    private ObservableCollection<INodeViewModel> _selectedNodes;

    public ObservableCollection<INodeViewModel> SelectedNodes
    {
        get { return _selectedNodes; }
        set
        {
            _selectedNodes = value;
            System.Diagnostics.Debug.WriteLine("Setting selected nodes");

            foreach (var nodeViewModel in _selectedNodes)
            {
                System.Diagnostics.Debug.WriteLine(nodeViewModel.Name);
            }

            RaisePropertyChanged(() => SelectedNodes);
            RaisePropertyChanged(() => ShowContextMenu);
            RaisePropertyChanged(() => MenuItems);
        }
    }

    public bool ShowContextMenu
    {
        get
        {
            var canDisplay = _contextMenuProvider.GetMenuItemsByNodeContext(SelectedNodes);
                return !canDisplay.IsNullOrEmpty();
        }
    }

    private ObservableCollection<IMenuItem> GetMenuItems()
    {
        var items = _contextMenuProvider.GetAllMenuItems(SelectedNodes);
        var menuItems = new ObservableCollection<IMenuItem>(items);
        return menuItems;
    }
}

私が直面している問題は次のとおりです。どの時点でメニュー項目をフェッチする必要があるのか​​ わかりません.selectednodesコレクションが作成されている間、またはユーザーが右クリックしているときにそれを行う必要がありますか? ツリービューのノードを右クリックしているときに、ツリービューのコンテキストメニューバインディングを更新するにはどうすればよいですか?

注: 選択目的で NodeViewModel に選択されたプロパティがあります。

ありがとう -マイク

4

0 に答える 0