Caliburn.micro получить выбранный элемент дерева просмотра по контекстному меню onclick - PullRequest
0 голосов
/ 27 января 2019

У меня есть задача использовать контекстное меню в древовидном представлении и передать элемент выбранного древовидного представления в ViewModel, щелкнув элемент contextmenu.

Вот мой xaml:

<Window.Resources>
  <HierarchicalDataTemplate x:Key="Ufps"
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding Id}" />
            <TextBlock Margin="5 0 0 0" Text="{Binding Name}" />
        </StackPanel>
  </HierarchicalDataTemplate>
</Window.Resources>
........
........
<TreeView x:Name="TrvUfpsDictionary" Height="222" Canvas.Left="25" 
  Canvas.Top="280" Width="545"
  Background="AliceBlue" 
  ItemsSource="{Binding Path=Ufps, Mode=OneWay}" 
  ItemTemplate="{StaticResource Ufps}">
        <TreeView.ContextMenu>
          <ContextMenu>
            <MenuItem Header="Add Element"
             cal:Message.Attach="[Event Click] = [Action AddElement(TrvUfpsDictionary.SelectedItem)]"
                />
                ................
            </ContextMenu>
        </TreeView.ContextMenu>           
    </TreeView>
........
<Button Content="Test" Canvas.Left="475" Canvas.Top="568" Width="75"
 cal:Message.Attach="[Event Click] = [Action AddElement(TrvUfpsDictionary.SelectedItem)]"/>

И здесь все простоКод ViewModel:

  public class UserSettingsViewModel : PropertyChangedBase
  {
   ..........

   public void AddElement(object selectedItem)
    {         
       MessageBox.Show("Element added! "+selectedItem.?GetHashCode());            
    }
   ..........
  }

Теперь я застрял с ним.Когда я выбрал элемент дерева, а затем нажал кнопку «Тест» - он работает нормально, он передает выбранный элемент «AddElement» в моей виртуальной машине.НО, когда я делаю то же самое с contextmenu - он всегда пропускает ноль.Я что-то пропустил?

РЕДАКТИРОВАТЬ Я сделал простое приложение с описанной проблемой.https://github.com/whizzzkey/WpfApp1

1 Ответ

0 голосов
/ 27 января 2019

Возможно, вам придется переместить контекстное меню дальше в TreeView, в шаблон элемента и добавить контекстное меню к метке / текстовому блоку, которые есть в узлах.

Например, рассмотрим следующее дерево сотрудников (эмулирующее, поскольку я не знаю вашу структуру данных),

<TreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding Positions}" >
                    <Label Content="{Binding DepartmentName}"/>
                    <HierarchicalDataTemplate.ItemTemplate>
                        <HierarchicalDataTemplate ItemsSource="{Binding Employees}" >
                            <Label Content="{Binding PositionName}"  Tag="{Binding DataContext, ElementName=TestControl}" >
                                <Label.ContextMenu>
                                    <ContextMenu cal:Action.TargetWithoutContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
                                        <MenuItem Header="Add Element" cal:Message.Attach="[Event Click] = [Action AddElement($datacontext)]"/>
                                    </ContextMenu>
                                </Label.ContextMenu>
                            </Label>
                            <HierarchicalDataTemplate.ItemTemplate>
                                <DataTemplate>
                                    <Label Content="{Binding EmployeeName}" Tag="{Binding DataContext, ElementName=TestControl}">
                                        <Label.ContextMenu>
                                            <ContextMenu cal:Action.TargetWithoutContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
                                                <MenuItem Header="Add Element" cal:Message.Attach="[Event Click] = [Action AddElement($datacontext)]"
                />
                                            </ContextMenu>
                                        </Label.ContextMenu>
                                    </Label>
                                </DataTemplate>
                            </HierarchicalDataTemplate.ItemTemplate>
                        </HierarchicalDataTemplate>
                    </HierarchicalDataTemplate.ItemTemplate>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>

Здесь следует отметить пару важных моментов. Поскольку ваш метод существует в ViewModel, и вы должны убедиться, что DataContext указывает на вашу ViewModel, а не на тип элемента, который привязан к узлу.

Для этого вам нужно использовать cal:Action.TargetWithoutContext. В следующей строке определение метки гарантирует, что у нас есть доступ к DataContext представления.

Tag="{Binding DataContext, ElementName=TestControl}" 

Хотя следующая строка гарантирует, что мы правильно установили привязки (к ViewModel). TestControl - это x: Name для вашего UserControl

cal:Action.TargetWithoutContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}"

Наконец, действие Click будет изменено следующим образом.

cal:Message.Attach="[Event Click] = [Action AddElement($datacontext)]"

Это обеспечит вызов Action вашего ViewModel с переданным правильным параметром.

Обновление

Исходя из вашего комментария и кода, следующие изменения необходимы.

Определение окна : Добавить x: Имя

<Window
        x:Class="WpfApp1.Views.ShellView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:cal="http://www.caliburnproject.org"
        Title="XmlData Tree Test"
        x:Name="TestControl"
        Width="250"
        Height="350"
        >

Корневой иерархический шаблон Связывание источника элемента с тегом размещается в TextBlock, а у относительного источника - Self.

<HierarchicalDataTemplate DataType="root" ItemsSource="{Binding XPath=./*}" >
            <StackPanel Orientation="Horizontal">
                <TextBlock Margin="0" Text="ROOT"  Tag="{Binding DataContext, ElementName=TestControl}">
                    <TextBlock.ContextMenu>
                        <ContextMenu
                        cal:Action.TargetWithoutContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
                            <MenuItem Header="Add Element" cal:Message.Attach="[Event Click] = [Action AddElement($datacontext)]" />
                        </ContextMenu>
                    </TextBlock.ContextMenu>
                    </TextBlock>
            </StackPanel>
        </HierarchicalDataTemplate>

Иерархический шаблон для узла

<HierarchicalDataTemplate DataType="Node"
                                  ItemsSource="{Binding XPath=./*}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Margin="0"
                           Text="Node:" />
                <TextBlock Margin="5,0,0,0"  Tag="{Binding DataContext, ElementName=TestControl}"
                           Text="{Binding XPath=@name}" >
                    <TextBlock.ContextMenu>
                        <ContextMenu
                            cal:Action.TargetWithoutContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
                            <MenuItem Header="Add Element" cal:Message.Attach="[Event Click] = [Action AddElement($datacontext)]" />
                        </ContextMenu>
                    </TextBlock.ContextMenu>
                </TextBlock>
            </StackPanel>
        </HierarchicalDataTemplate>

Пример вывода, Для корня

enter image description here

для узла, enter image description here

...