Привязка команды ReactiveUI + ContextMenu в ресурсах =? - PullRequest
0 голосов
/ 06 декабря 2018

У меня есть ReactiveUserControl.В этом у меня есть TreeView, который использует ContextMenus, определенный ниже.Конвертер позволяет мне иметь разные меню для разных типов элементов в дереве.

Теперь я хочу использовать код, приведенный ниже, для привязки команды реагирующего ключа для MenuItems.Но я не могу получить доступ к XName MenuItem, когда ContextMenu находится в Ресурсах.

И вопрос: Как я могу получить привязку следующим образом:

this.BindCommand(ViewModel, vm => vm.RunCommand, v => v.XNameOfAContexdtMenuItem);

Для работы с MenuItems вкаждый ContextMenu?

    <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 нельзя получить доступ из кода позади.

1 Ответ

0 голосов
/ 14 декабря 2018

Итак, я провел некоторое тестирование, и лучший способ найти это - не использовать 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>

Код, стоящий за привязкой ReactiveUIдля элементов TreeView:

   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 должны иметь ссылку на команду, команды не могут быть в ViewModel TreeView.

 <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>));

Вот и все, я думаю.Я надеюсь, что кто-то еще находит это полезным:)

...