C# 获取GridViewColumn的父级
是否有方法获取GridViewColumn的父级(ListView) 我试过LogicalTreeHelper和VisualTreeHelper,但没有骰子 我可以分享一个你尝试过的有点搞笑的东西,它很有效,但丑陋并不能描述它: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
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;
}
}
}