C# 获取GridViewColumn的父级

C# 获取GridViewColumn的父级,c#,wpf,gridview,attached-properties,C#,Wpf,Gridview,Attached Properties,是否有方法获取GridViewColumn的父级(ListView) 我试过LogicalTreeHelper和VisualTreeHelper,但没有骰子 我可以分享一个你尝试过的有点搞笑的东西,它很有效,但丑陋并不能描述它: public class Prototype { [Test, RequiresSTA] public void HackGetParent() { var lw = new ListView(); var vie

是否有方法获取GridViewColumn的父级(ListView)

我试过LogicalTreeHelper和VisualTreeHelper,但没有骰子

我可以分享一个你尝试过的有点搞笑的东西,它很有效,但丑陋并不能描述它:

public class Prototype
{
    [Test, RequiresSTA]
    public void HackGetParent()
    {
        var lw = new ListView();
        var view = new GridView();
        var gvc = new GridViewColumn();
        view.Columns.Add(gvc);
        lw.View = view;
        var ancestor = new Ancestor<ListView>();

        var binding = new Binding
        {
            RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(ListView), 1),
            Converter = new GetAncestorConverter<ListView>(), // Use converter to hack out the parent
            ConverterParameter = ancestor // conveterparameter used to return the parent
        };
        BindingOperations.SetBinding(gvc, GridViewColumn.WidthProperty, binding);

        lw.Items.Add(DateTime.Now); // think it cannot be empty for resolve to work
        ResolveBinding(lw);
        Assert.AreEqual(lw, ancestor.Instance);
    }

    private void ResolveBinding(FrameworkElement element)
    {
        element.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
        element.Arrange(new Rect(element.DesiredSize));
        element.UpdateLayout();
    }
}
公共类原型
{
[测试,要求ta]
public-void HackGetParent()
{
var lw=新的ListView();
var view=new GridView();
var gvc=新的GridViewColumn();
view.Columns.Add(gvc);
视图=视图;
var祖先=新祖先();
var绑定=新绑定
{
RelativeSource=新的RelativeSource(RelativeSourceMode.FindAncestor,类型为(ListView),1),
Converter=new GetAncestorConverter(),//使用Converter清除父级
ConverterParameter=祖先//用于返回父级的ConverterParameter
};
BindingOperations.SetBinding(gvc、GridViewColumn.WidthProperty、binding);
lw.Items.Add(DateTime.Now);//认为它不能为空,解析才能工作
可分解绑定(lw);
aresequal(lw,祖先.Instance);
}
私有void ResolveBinding(FrameworkElement元素)
{
元素。度量(新大小(双正不确定度,双正不确定度));
element.Arrange(新的Rect(element.DesiredSize));
元素UpdateLayout();
}
}
公共类GetAncestorConverter:IValueConverter
{
公共对象转换(对象值、类型、对象参数、CultureInfo区域性)
{
var祖先=(祖先)参数;
Instance=(T)值;
返回null;
}
公共对象转换回(对象o、类型类型、对象参数、CultureInfo区域性)
{
抛出新的NotSupportedException();
}
}
公共类祖先
{
公共T实例{get;set;}
}

不幸的是,您想要的东西隐藏在
DependencyObject
InheritanceContext
的内部属性后面,因此访问它的唯一方法是通过反射。因此,如果您对此感到满意,那么此解决方案将起作用

public class Prototype
{
    [Test, RequiresSTA]
    public void HackReflectionGetParent()
    {
        var lw = new ListView();
        var view = new GridView();
        var gvc = new GridViewColumn();
        view.Columns.Add(gvc);
        lw.View = view;

        var resolvedLw = gvc.GetParents().OfType<ListView>().FirstOrDefault();
        Assert.AreEqual(lw, resolvedLw);
    }
}

public static class DependencyObjectExtensions
{
    private static readonly PropertyInfo InheritanceContextProp = typeof (DependencyObject).GetProperty("InheritanceContext", BindingFlags.NonPublic | BindingFlags.Instance);

    public static IEnumerable<DependencyObject> GetParents(this DependencyObject child)
    {
        while (child != null)
        {
            var parent = LogicalTreeHelper.GetParent(child);
            if (parent == null)
            {
                if (child is FrameworkElement)
                {
                    parent = VisualTreeHelper.GetParent(child);
                }
                if (parent == null && child is ContentElement)
                {
                    parent = ContentOperations.GetParent((ContentElement) child);
                }
                if (parent == null)
                {
                    parent = InheritanceContextProp.GetValue(child, null) as DependencyObject;
                }
            }
            child = parent;
            yield return parent;
        }
    }
}
公共类原型
{
[测试,要求ta]
public void HackReflectionGetParent()
{
var lw=新的ListView();
var view=new GridView();
var gvc=新的GridViewColumn();
view.Columns.Add(gvc);
视图=视图;
var resolvedLw=gvc.GetParents().OfType().FirstOrDefault();
断言.AreEqual(lw,resolvedLw);
}
}
公共静态类DependencyObjectExtensions
{
私有静态只读属性info InheritanceContextProp=typeof(DependencyObject).GetProperty(“InheritanceContext”,BindingFlags.NonPublic | BindingFlags.Instance);
公共静态IEnumerable GetParents(此DependencyObject子对象)
{
while(child!=null)
{
var parent=LogicalTreeHelper.GetParent(子级);
如果(父项==null)
{
if(子元素是FrameworkElement)
{
父级=VisualTreeHelper.GetParent(子级);
}
if(parent==null&&child是ContentElement)
{
parent=ContentOperations.GetParent((ContentElement)子级);
}
如果(父项==null)
{
parent=InheritanceContextProp.GetValue(子级,null)作为DependencyObject;
}
}
孩子=父母;
收益母公司;
}
}
}

早在2009年就有关于这件事被公之于众的报道,但什么都没有发生,所以我怀疑它是否会被公之于众。也就是说,该属性在框架内被广泛使用,并且适用于其他框架程序集,因此我认为这是一个非常安全的赌注,它也不会很快改变。

我知道这是3年前提出的问题,但我现在需要这样做几次,而且我总是会遇到这个答案,所以我估计其他有这个问题的人也会有同样的问题

我找到了一个简单的方法来解决这个问题和类似的问题,只要您愿意在listview或gridview的父对象实例化时添加一些代码

长话短说:我利用.NET System.Collections.Generic.Dictionary功能创建这样一个字典(关于“通知我的对象类型”、“需要检索的对象类型”),例如字典(关于GridViewColumn、ListView),并在父对象实例化时加载它。如果我得到一个GridViewColumn,并且我需要知道它的“父”listview是什么,那么我只需参考这个字典就可以得到它


似乎适合我的工作:)

甜蜜的扩展方法,认为它会有用,泰先生。示例代码通常是一个很好的答案。我没有足够的理解力来支持它现在的样子。
public class Ancestor<T>
{
    public T Instance { get; set; }
}
public class Prototype
{
    [Test, RequiresSTA]
    public void HackReflectionGetParent()
    {
        var lw = new ListView();
        var view = new GridView();
        var gvc = new GridViewColumn();
        view.Columns.Add(gvc);
        lw.View = view;

        var resolvedLw = gvc.GetParents().OfType<ListView>().FirstOrDefault();
        Assert.AreEqual(lw, resolvedLw);
    }
}

public static class DependencyObjectExtensions
{
    private static readonly PropertyInfo InheritanceContextProp = typeof (DependencyObject).GetProperty("InheritanceContext", BindingFlags.NonPublic | BindingFlags.Instance);

    public static IEnumerable<DependencyObject> GetParents(this DependencyObject child)
    {
        while (child != null)
        {
            var parent = LogicalTreeHelper.GetParent(child);
            if (parent == null)
            {
                if (child is FrameworkElement)
                {
                    parent = VisualTreeHelper.GetParent(child);
                }
                if (parent == null && child is ContentElement)
                {
                    parent = ContentOperations.GetParent((ContentElement) child);
                }
                if (parent == null)
                {
                    parent = InheritanceContextProp.GetValue(child, null) as DependencyObject;
                }
            }
            child = parent;
            yield return parent;
        }
    }
}