Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get parent for GridViewColumn

Is there a way to get the parent (ListView) for a GridViewColumn?

I have tried with LogicalTreeHelper and VisualTreeHelper but no dice.

I can share a what-have-you-tried that is a bit funny, it works but ugly is not close to describing it:

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; }
}
like image 234
Johan Larsson Avatar asked Jan 08 '14 00:01

Johan Larsson


People also ask

What is GridView column in Windows system controls?

System. Windows. Controls System. Windows. Controls Represents a column that displays data. Localizability Attribute Content Property Attribute Style Typed Property Attribute The following example shows how to define GridViewColumn objects for a GridView. A GridViewColumn is used by the GridView view mode to display a column of data.

How to get the column header from the column in gridviewcolumn?

Different ways. There is no universal way to find GridViewColumnHeader from GridViewColumn that would be convenient and doesn’t impact performance. But in different situations you can choose appropriate method from those described below. They are arranged below in descending order from architectural point of view from more convenient to less one.

How to get the detailview of a Grid item?

To get DetailView you can use GridView.GetDetailView method and to get filtered rows you can use undocumented GridView.DataController.GetAllFilteredAndSortedRows method. If DetailView is null then you need to get «DevExpress filter engine» and use it with your GridItemModel.Inventory list. You can get this engine from DevExpress controls such:

How to display a column of data in a listview?

A GridViewColumn is used by the GridView view mode to display a column of data. The ListView that implements the GridView view mode provides the data for the column. You use data binding to specify the data for the GridViewColumn. You can use the DisplayMemberBinding to define the data to display in a column.


1 Answers

What you want is unfortunately hidden behind an internal property of the DependencyObject InheritanceContext so the only way to access it is via reflection. So if you are comfortable with that then this solution will work.

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;
        }
    }
}

There was some discussion about this being made public back in 2009 and nothing has happened so I doubt it will be. That said the property is used extensively within the framework and is Friend Visible to other framework assemblies so I think it is a pretty safe bet it isn't going to change soon either.

like image 171
David Ewen Avatar answered Oct 15 '22 06:10

David Ewen