从子xaml检索treeviewitem的datacontext

xx默认xx

我有一个DataBound树视图,可从中创建/显示treeviewitems并具有上下文菜单。这工作正常。然后,我尝试使用自定义menuitem类,以便可以通过从contextmenu菜单中触发的命令来检索treeviewitem的datacontext。抱歉,这令人困惑。我这样做可能走错了路。

这是我的xaml。

<UserControl x:Class="Pipeline_General.Custom_Controls.ProjectTree"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:pm="clr-namespace:Pipeline_General"
         mc:Ignorable="d" 
         DataContext = "{Binding RelativeSource={RelativeSource Self}}"
         d:DesignHeight="300" d:DesignWidth="300">
<Grid>
    <TreeView Name="StructureTree" Background="{x:Static pm:myBrushes.defaultBG}" ItemsSource="{Binding ProjectList}">
        <TreeView.ItemContainerStyle>
            <Style TargetType="{x:Type TreeViewItem}">
                <Setter Property="IsExpanded" Value="True"/>
                <Setter Property="Margin" Value="5,5,5,5" />
                <Setter Property="ContextMenu">
                    <Setter.Value>
                        <ContextMenu Background="{x:Static pm:myBrushes.defaultBG}" Foreground="{x:Static pm:myBrushes.gray}">
                            <pm:ProjectTreeMenuItem Header="Add Episode.." 
                                    Element="{Binding Path=DataContext, RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}}}"
                                      Command="{x:Static pm:MyCommands.AddEpCommand}" 
                                      CommandParameter="{Binding RelativeSource={RelativeSource Self}}"
                                      Margin="20,0"/>
                            <pm:ProjectTreeMenuItem Header="Add Sequence.." 
                                      Element="{Binding Path=DataContext, RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}}}"
                                      Command="{x:Static pm:MyCommands.AddSeqCommand}" 
                                      CommandParameter="{Binding RelativeSource={RelativeSource Self}}"
                                      Margin="20,0"/>
                            <pm:ProjectTreeMenuItem Header="Add Scene.." 
                                        Element="{Binding Path=DataContext, RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}}}"
                                      Command="{x:Static pm:MyCommands.AddScCommand}" 
                                      CommandParameter="{Binding RelativeSource={RelativeSource Self}}"
                                      Margin="20,0"/>
                        </ContextMenu>
                    </Setter.Value>
                </Setter>
            </Style>
        </TreeView.ItemContainerStyle>
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate DataType="{x:Type pm:ProjectRoot}" ItemsSource="{Binding Episodes}">
                <TextBlock Text="{Binding Path=Title}" Foreground="{x:Static pm:myBrushes.pink}"
                           FontFamily="Calibri" FontSize="18"/>
                <HierarchicalDataTemplate.ItemContainerStyle>
                    <Style TargetType="{x:Type TreeViewItem}">
                        <Setter Property="IsExpanded" Value="True"/>
                        <Setter Property="Margin" Value="5,5,5,5" />
                        <Setter Property="ContextMenu">
                            <Setter.Value>
                                <ContextMenu Background="{x:Static pm:myBrushes.defaultBG}" Foreground="{x:Static pm:myBrushes.gray}">
                                    <pm:ProjectTreeMenuItem Header="Add Sequence.."  
                                     Element="{Binding Path=DataContext, RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}}}"
                                     Command="{x:Static pm:MyCommands.AddSeqCommand}" 
                                      CommandParameter="{Binding RelativeSource={RelativeSource Self}}"
                                      Margin="20,0"/>
                                    <pm:ProjectTreeMenuItem Header="Add Scene.."
                                      Element="{Binding Path=DataContext, RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}}}"
                                      Command="{x:Static pm:MyCommands.AddScCommand}" 
                                      CommandParameter="{Binding RelativeSource={RelativeSource Self}}"
                                      Margin="20,0"/>
                                    <Separator Height="15" Margin="20,0"/>
                                    <pm:ProjectTreeMenuItem Header="Cut" 
                                    Element="{Binding Path=DataContext, RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}}}"
                                    Command="{x:Static pm:MyCommands.CutCommand}" 
                                      CommandParameter="{Binding RelativeSource={RelativeSource Self}}"
                                      Margin="20,0"/>
                                    <pm:ProjectTreeMenuItem Header="Un-Cut" 
                                    Element="{Binding Path=DataContext, RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}}}"
                                    Command="{x:Static pm:MyCommands.UnCutCommand}" 
                                      CommandParameter="{Binding RelativeSource={RelativeSource Self}}"
                                      Margin="20,0"/>
                                </ContextMenu>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </HierarchicalDataTemplate.ItemContainerStyle>


                <HierarchicalDataTemplate.ItemTemplate>
                    <HierarchicalDataTemplate DataType="{x:Type pm:Episode}" ItemsSource="{Binding Sequences}">
                        <TextBlock Text="{Binding Path=Key}" Foreground="{x:Static pm:myBrushes.yellow}"
                                           FontFamily="Calibri" FontSize="14"/>
                        <HierarchicalDataTemplate.ItemContainerStyle>
                            <Style TargetType="{x:Type TreeViewItem}">
                                <Setter Property="IsExpanded" Value="True"/>
                                <Setter Property="Margin" Value="5,5,5,5" />
                                <Setter Property="ContextMenu">
                                    <Setter.Value>
                                        <ContextMenu Background="{x:Static pm:myBrushes.defaultBG}" Foreground="{x:Static pm:myBrushes.gray}">
                                            <pm:ProjectTreeMenuItem Header="Add Scene.." 
                                             Element="{Binding Path=DataContext, RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}}}"
                                             Command="{x:Static pm:MyCommands.AddScCommand}" 
                                            CommandParameter="{Binding RelativeSource={RelativeSource Self}}"
                                            Margin="20,0"/>
                                            <Separator Height="15" Margin="20,0"/>
                                            <pm:ProjectTreeMenuItem Header="Cut" 
                                            Element="{Binding Path=DataContext, RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}}}"
                                            Command="{x:Static pm:MyCommands.CutCommand}" 
                                            CommandParameter="{Binding RelativeSource={RelativeSource Self}}"
                                            Margin="20,0"/>
                                            <pm:ProjectTreeMenuItem Header="Un-Cut" 
                                             Element="{Binding Path=DataContext, RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}}}"
                                            Command="{x:Static pm:MyCommands.UnCutCommand}" 
                                            CommandParameter="{Binding RelativeSource={RelativeSource Self}}"
                                             Margin="20,0"/>
                                        </ContextMenu>
                                    </Setter.Value>
                                </Setter>
                            </Style>
                        </HierarchicalDataTemplate.ItemContainerStyle>

                        <HierarchicalDataTemplate.ItemTemplate>
                            <HierarchicalDataTemplate DataType="{x:Type pm:Sequence}" ItemsSource="{Binding Scenes}">
                                <TextBlock Text="{Binding Path=Key}" Foreground="{x:Static pm:myBrushes.yellow}"
                                           FontFamily="Calibri" FontSize="14"/>
                                <HierarchicalDataTemplate.ItemContainerStyle>
                                    <Style TargetType="{x:Type TreeViewItem}">
                                        <Setter Property="ContextMenu">
                                            <Setter.Value>
                                                <ContextMenu Background="{x:Static pm:myBrushes.defaultBG}" Foreground="{x:Static pm:myBrushes.gray}">
                                                    <pm:ProjectTreeMenuItem Header="Cut" 
                                                        Element="{Binding Path=DataContext, RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}}}"
                                                        Command="{x:Static pm:MyCommands.CutCommand}" 
                                                        CommandParameter="{Binding RelativeSource={RelativeSource Self}}"
                                                        Margin="20,0"/>
                                                    <pm:ProjectTreeMenuItem Header="Un-Cut" 
                                                         Element="{Binding Path=DataContext, RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}}}"
                                                        Command="{x:Static pm:MyCommands.UnCutCommand}" 
                                                        CommandParameter="{Binding RelativeSource={RelativeSource Self}}"
                                                         Margin="20,0"/>
                                                </ContextMenu>
                                            </Setter.Value>
                                        </Setter>
                                    </Style>
                                </HierarchicalDataTemplate.ItemContainerStyle>
                            </HierarchicalDataTemplate>
                        </HierarchicalDataTemplate.ItemTemplate>
                    </HierarchicalDataTemplate>
                </HierarchicalDataTemplate.ItemTemplate>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>
</Grid>

以及我的自定义菜单项类和命令。

public static class MyCommands
{
    static MyCommands()
    {
        AddEpCommand = new SimpleDelegateCommand(p =>
        {
            var menuItem = p as ProjectTreeMenuItem;
            var Element = menuItem.Element as ProjectElement;
            Console.WriteLine(Element.Key);
            Console.WriteLine("EP");
        });

        AddSeqCommand = new SimpleDelegateCommand(p =>
        {
            var menuItem = p as ProjectTreeMenuItem;
            var Element = menuItem.Element as ProjectElement;
            Console.WriteLine(Element.Key);
            Console.WriteLine("SEQ");
        });

        AddScCommand = new SimpleDelegateCommand(p =>
        {
            var menuItem = p as ProjectTreeMenuItem;
            var Element = menuItem.Element as ProjectElement;
            Console.WriteLine(Element.Key);
            Console.WriteLine("SC");
        });

        CutCommand = new SimpleDelegateCommand(p =>
        {
            var menuItem = p as ProjectTreeMenuItem;
            var Element = menuItem.Element as ProjectElement;
            Console.WriteLine(Element.Key);
            Console.WriteLine("SC");
        });

        UnCutCommand = new SimpleDelegateCommand(p =>
        {
            var menuItem = p as ProjectTreeMenuItem;
            var Element = menuItem.Element as ProjectElement;
            Console.WriteLine(Element.Key);
            Console.WriteLine("SC");
        });
    }

    public static ICommand AddEpCommand { get; set; }
    public static ICommand AddSeqCommand { get; set; }
    public static ICommand AddScCommand { get; set; }
    public static ICommand CutCommand { get; set; }
    public static ICommand UnCutCommand { get; set; }
}

public class SimpleDelegateCommand : ICommand
{
    public SimpleDelegateCommand(Action<object> executeAction)
    {
        _executeAction = executeAction;
    }

    private Action<object> _executeAction;

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        _executeAction(parameter);
    }
}

public class ProjectTreeMenuItem : MenuItem
{
    #region Element (DependencyProperty)
    public ProjectElement Element
    {
        get { return (ProjectElement)GetValue(ElementProperty); }
        set { SetValue(ElementProperty, value); }
    }
    public static readonly DependencyProperty ElementProperty =
        DependencyProperty.Register("Element", typeof(ProjectElement), typeof(ProjectTreeMenuItem),
          new PropertyMetadata { PropertyChangedCallback = ElementChanged });
    private static void ElementChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ProjectTreeMenuItem so = d as ProjectTreeMenuItem;
        if (so != null && e.NewValue != null)
        {
            so.Element = (ProjectElement)e.NewValue;
            Console.WriteLine("HERE " + so.Element.Title);
        }
    }
    #endregion

    public ProjectTreeMenuItem()
        :base()
    {

    }
}

projectElement类(在项目中的其他数百个地方都使用过)具有String Key,String Title属性,该属性在其他地方也可以正常使用。我很确定我的问题在于通过datacontext通过xaml设置Element属性。

xx默认xx

最终弄清楚了。.我使用menuitem的command属性,并使用它直接发送回数据上下文,而不是在自定义菜单项类上使用依赖项属性。

更大的问题是,我试图使用从可视树中找到祖先,这在上下文菜单中不起作用,而且我还认为,因为我在hierachialdatatemplate中,因此无论如何都无法工作。

以下是技巧。

                          <ContextMenu Background="{x:Static pm:myBrushes.defaultBG}" Foreground="{x:Static pm:myBrushes.gray}"
                                     DataContext="{Binding PlacementTarget, RelativeSource={RelativeSource Self}}">
                            <MenuItem Header="Add Episode.." 
                                      Command="{x:Static pm:MyCommands.AddEpCommand}" 
                                      CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor,
                                            AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.DataContext}"
                                      Margin="20,0"/>
                            <MenuItem Header="Add Sequence.." 
                                      Command="{x:Static pm:MyCommands.AddSeqCommand}" 
                                      CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor,
                                            AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.DataContext}"
                                      Margin="20,0"/>
                            <MenuItem Header="Add Scene.." 
                                      Command="{x:Static pm:MyCommands.AddScCommand}" 
                                      CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor,
                                            AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.DataContext}"
                                      Margin="20,0"/>
                        </ContextMenu>

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在WPF中的XAML中设置DataContext

WPF / XAML绑定:使用实际的DataContext

Firebase按键从子级检索数据

从子组件检索自动完成输入值

仅从子文档中检索某些字段

从子表/子表中检索MySQL条目

是否可以从子级DataContext(ViewModel)中获取父视图元素的DataContext(ViewModel)?

如何从代码隐藏中访问XAML中已指定的DataContext?

在XAML中设置时访问代码中的DataContext实例

如何在XAML的ListView.ItemTemplate中引用ListView DataContext?

无法从子流程check_output检索输出

Flutter:从子级检索顶级状态将返回null

父级未成功从子级检索数据

从子视图的父视图控制器中检索数组

fork()之后无法从子级检索mmap共享内存

从子目录检索文件名

从子选择器检索数据属性的值

Swift UI 如何从子视图中检索状态

从子列表中检索升序整数的所有可能组合

TreeViewItem 的 IsSelected 属性的触发器在 xaml 中不起作用?

如何使用“ XAML工具包中的材料设计”控件拉伸TreeViewItem

如何做到这一点.DataContext = this:在XAML中....例如,例如<Window.DataContext> <local:MainWindow /> </ Window.DataContext>->

将DataContext设置为XAML中的当前代码隐藏对象

XAML 中的 WPF DataContext,为什么以及正确的方法是什么

DataContext是否在XAML上分配指向其在类后面的代码

将代码隐藏的定义属性绑定到XAML中的DataContext属性?

VB.net XAML UWP共享类可以用于DataContext吗?

WPF:XAML:给 DataContext 一个名称而不实例化它

已将DataContext设置为视图模型时在XAML中引用视图成员