1

我有一个 TreeView 我正在填充并向每个项目添加一个 ContextMenu。问题是在我的 ViewModel 中,TreeView ItemSource 绑定到 ViewModel 本身的一个属性。当我尝试再次引用 ViewModel 上的某些属性时,我似乎无法让它工作。

<TreeView Grid.ColumnSpan="1" Grid.Row="1" HorizontalAlignment="Stretch" ItemsSource="{Binding ModelItems}" SelectedTreeItem="{Binding SelectedItem, Mode=TwoWay}" VerticalAlignment="Stretch" Grid.RowSpan="3" Margin="5">
<TreeView.ItemTemplate>
    <HierarchicalDataTemplate ItemsSource="{Binding Models}">
        <TextBlock Text="{Binding Header, Mode=TwoWay}"  ToolTip="{Binding Tooltip, Mode=TwoWay}">
            <TextBlock.ContextMenu>
                <ContextMenu>
                    <MenuItem Header="Server" Visibility="{Binding Path=IsServerVisible}">
                        <MenuItem Header="Add" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Windows:MainWindow}}, Path=ViewModel:ViewModel.AddServerCommand}"/>
                        <MenuItem Header="Edit" />
                        <MenuItem Header="Delete" />
                    </MenuItem>
                    <MenuItem Header="Config" Visibility="{Binding Path=IsConfigVisible}">
                        <MenuItem Header="Fetch" />
                        <MenuItem Header="Edit" />
                        <MenuItem Header="Save" />
                    </MenuItem>     
                </ContextMenu>
            </TextBlock.ContextMenu>
        </TextBlock>
    </HierarchicalDataTemplate>                
</TreeView.ItemTemplate>

StackOverflow 上的前一篇文章指出了使用 RelativeSource 正确绑定到 MainWindow 上的 ViewModel 的方向。但是,当我运行该应用程序时,该命令不起作用,并且“输出”窗口没有生成任何我可以看到的绑定或 xaml 错误。

基本上可见性绑定有效,因为这些属性存在于“模型”项目上。但是,我希望将所有内容都移至 ViewModel,尤其是 Command。

谁能发现我在这里做错了什么?

4

3 回答 3

3

这里要记住的关键是上下文菜单不是可视化树的一部分

因此,它们不会继承与它们所属的用于绑定的控件相同的源。处理这个问题的方法是绑定到placement targetContextMenu 本身。但是,由于您想在 ViewModel 类中为 Command 绑定它,所以DataContext in Tag将 TextBlock 放置并在您的命令绑定中使用,如下所示 -

<HierarchicalDataTemplate ItemsSource="{Binding Models}">
    <TextBlock Text="{Binding Header}"
               Tag="{Binding DataContext, RelativeSource=
               {RelativeSource Mode=FindAncestor, AncestorType=Window}}">
         <TextBlock.ContextMenu>
              <ContextMenu>
                  <MenuItem Header="Server" Command="{Binding 
                            PlacementTarget.Tag.AddServerCommand,
                            RelativeSource={RelativeSource Mode=FindAncestor, 
                            AncestorType=ContextMenu}}"/>
               </ContextMenu>
          </TextBlock.ContextMenu>
      </TextBlock>
</HierarchicalDataTemplate>

用于与上述类似的其他绑定,它将按照您的意愿工作。

于 2012-11-15T06:16:28.883 回答
0

代替

<MenuItem Header="Add" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Windows:MainWindow}}, Path=ViewModel:ViewModel.AddServerCommand}"/>

尝试

<MenuItem Header="Add" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Windows:MainWindow}}, Path=DataContext.AddServerCommand}"/>

你的 ViewModel 不是你的 DataContext 吗?

于 2012-11-15T04:25:41.033 回答
0

因为您没有发布完整的 .xaml,所以让我们使用树视图的数据上下文。因为 RelativeSource 让我们可以访问 TreeView,所以您需要在 Binding Path 中使用 DataContext,因为这是对您的 ViewModel 的引用。

Command="{Binding Path="DataContext.AddServerCommand" RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeView}}}"
于 2012-11-15T02:38:42.950 回答