ノード階層を持つ 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 に選択されたプロパティがあります。
ありがとう -マイク