c# - ReactiveUI 命令绑定 + 资源中的 ContextMenu =?
问题描述
我有一个 ReactiveUserControl。在这个我有一个使用下面定义的 ContextMenus 的 TreeView。转换器使我能够为树中的不同项目类型提供不同的菜单。
现在我想做的是使用后面的代码为 MenuItems 做一个响应式命令绑定。但是当 ContextMenu 在资源中时,我无法访问 MenuItem 的 XName。
还有一个问题:我怎样才能得到这样的绑定:
this.BindCommand(ViewModel, vm => vm.RunCommand, v => v.XNameOfAContexdtMenuItem);
要使用每个 ContextMenu 中的 MenuItems?
<StackPanel x:Name="MainPanel">
<StackPanel.Resources>
<ContextMenu x:Key="Menu_1" >
<MenuItem x:Name="Command_1" Header="Menu for ItemType_1 Command 1" Click="i_dont_want_to_use_this" />
<MenuItem x:Name="Command_2" Header="Menu for ItemType_1 Command 2"/>
</ContextMenu>
<ContextMenu x:Key="Menu_2" >
<MenuItem x:Name="Command_3" Header="Menu for ItemType_2 Command 3" />
<MenuItem x:Name="Command_4" Header="Menu for ItemType_2 Command 4"/>
</ContextMenu>
<conv:ContextMenuConverter x:Key="ContextMenuConverter"
WorkerMenu="{StaticResource Menu_1}"
JobMenu="{StaticResource Menu_2}"
/>
</StackPanel.Resources>
我还应该提到,如果我将 ContextMenu 放在 TreeView.Resources 中,它仍然无法访问,只要它位于任何资源中,就无法从后面的代码访问 XName。
解决方案
所以我做了一些测试,我能找到的最好方法是不在资源中使用 ContextMenu,而是使用“ViewModelViewHost”,如下面的代码:
<TreeView x:Name="TheTreeView">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding ListOfItemType_2 }" DataType="{x:Type local:ItemType_1ViewModel}">
<rxui:ViewModelViewHost ViewModel="{Binding}"/>
<HierarchicalDataTemplate.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:ItemType_2ViewModel }" >
<rxui:ViewModelViewHost ViewModel="{Binding}"/>
</HierarchicalDataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
TreeView 项的 ReactiveUI 绑定背后的代码:
public FunctionTreeView()
{
InitializeComponent();
this.WhenActivated(
dis =>
{
this.WhenAnyValue(x => x.ViewModel).BindTo(this, x => x.DataContext).DisposeWith(dis);
this.OneWayBind(ViewModel, vm => vm.ItemType_1ViewModelList , x => x.TheTreeView.ItemsSource).DisposeWith(dis);
});
}
然后在 ItemType_1View 和 ItemType_2View 中添加上下文菜单,这使得使用 ReactiveUI 绑定成为可能。唯一的缺点是ItemType_1ViewModel和ItemType_2ViewModel需要有对命令的引用,命令不能在TreeView的ViewModel中。
<UserControl.ContextMenu>
<ContextMenu>
<MenuItem x:Name="MenuItem_RunCommand" Header="Run" />
<MenuItem x:Name="MenuItem_InformationCommand" Header="Show Information"/>
</ContextMenu>
</UserControl.ContextMenu>
以及背后的代码:
public ItemType_2View()
{
InitializeComponent();
this.WhenActivated(dis =>
{
this.BindCommand(ViewModel, vm => vm.RunCommand, v => v.MenuItem_RunCommand).DisposeWith(dis);
});
还需要注册视图:
dependencyResolver.Register(() => new ItemType_1View (), typeof(IViewFor<ItemType_1ViewModel>));
dependencyResolver.Register(() => new ItemType_2View (), typeof(IViewFor<ItemType_2ViewModel>));
就是这样,我想。我希望其他人觉得这很有用:)
推荐阅读
- entity-framework - Linq 获取每个 Make into DTO 的模型列表
- amazon-web-services - 对于 col_a 中的每个不同值,生成一个新表
- javascript - 如何在javascript中将对象插入数组?
- node.js - 如何在 nodejs express mongodb 中使用多查询
- flutter - 如何在颤动中将视频播放器浮动在 youtube 等所有页面上?
- java - 如何从字符串 html 添加样式以在 android textview 中显示?
- typescript - “未找到模块:错误:无法解析 'electron-is-dev'”在电子和打字稿和 webpack 项目中
- installation - 如何使用 Homebrew 安装整个文件目录?
- nativescript - Nativescript - page.frame 未定义
- hyperledger-fabric - Hyperledger Fabric 从通道配置中删除组织导致错误