【问题标题】:Get parent for GridViewColumn获取 GridViewColumn 的父级
【发布时间】:2014-01-25 22:12:13
【问题描述】:

有没有办法获取 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();
    }
}
public class GetAncestorConverter<T> : IValueConverter
{
    public object Convert(object value, Type type, object parameter, CultureInfo culture)
    {
        var ancestor = (Ancestor<T>)parameter;
        ancestor.Instance = (T)value;
        return null;
    }

    public object ConvertBack(object o, Type type, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}
public class Ancestor<T>
{
    public T Instance { get; set; }
}

【问题讨论】:

    标签: c# wpf gridview attached-properties


    【解决方案1】:

    不幸的是,您想要的隐藏在 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;
            }
        }
    }
    

    some discussion 早在 2009 年就公开了这件事,但什么都没发生,所以我怀疑它会发生。也就是说,该属性在框架内被广泛使用,并且对于其他框架程序集是Friend Visible,所以我认为这是一个非常安全的赌注,它也不会很快改变。

    【讨论】:

    • 甜蜜的扩展方法,觉得很有用,先生。
    【解决方案2】:

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

    如果您愿意在实例化列表视图或网格视图的父对象时添加一些代码,我找到了解决此问题和类似问题的简单方法。

    长话短说:我利用 .NET System.Collections.Generic.Dictionary 功能创建这样一个字典(“我收到通知的对象类型”、“我需要检索的对象类型”),例如Dictionary (Of GridViewColumn, ListView) - 并在父对象的实例化时加载它。如果我然后,比如说,得到一个 GridViewColumn 并且我需要知道它的“父”列表视图是什么,我只需参考这个 Dictionary 来获取它。

    似乎适合我的工作:)

    【讨论】:

    • 示例代码通常是很好的答案。我还不够了解,无法像现在这样支持它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 2015-05-09
    • 2012-01-18
    • 1970-01-01
    • 1970-01-01
    • 2011-10-20
    相关资源
    最近更新 更多