I'm creating custom ItemsControl
that is derived from DataGrid
. I need to access ItemsHost that is the Panel
that actually holds rows of DataGrid
. I have seen som ugly tricks to do that but I consider them worse then using reflection.
So can I access ItemsHost using reflection ? And how ?
Asked
Active
Viewed 1,517 times
4

Rasto
- 17,204
- 47
- 154
- 245
-
Are you talking about this? http://stackoverflow.com/questions/691379/using-a-grid-as-an-itemshost – Nate Noonen Feb 21 '11 at 02:55
-
not exactly. See my answer below. – Rasto Feb 21 '11 at 03:24
2 Answers
6
Yes I can. It is simple - I've just created property in class inheriting from DataGrid
:
protected Panel ItemsHost {
get {
return (Panel) typeof (MultiSelector).InvokeMember("ItemsHost",
BindingFlags.NonPublic | BindingFlags.GetProperty | BindingFlags.Instance,
null, this, null);
}
}
It works like a charm :). I can get the value of ItemsHost
internal property of the ItemsControl
class. This way I can access any non-protected properties.

Rasto
- 17,204
- 47
- 154
- 245
-
I have no idea what this does or why this works, but for sure it does work with my ItemsControl :) – dain Jan 26 '12 at 15:27
-
1You could use `typeof(ItemsControl)` instead of `typeof(MultiSelector)`, that would work for all `ItemsControls` then. – Corentin Pane Mar 09 '21 at 10:38
0
If you're a fan of @rasto's answer, but you're concerned about the performance of reflection, this implementation uses expression trees to create a strongly typed Func<ItemsControl, Panel>
. You incur the reflection cost only once. You can also wrap it up in a handy extension method...
public static class ItemsControlExtensions
{
private static readonly Lazy<Func<ItemsControl, Panel?>> getItemsHost
= new (CreateGetItemsHostLambda);
private static Func<ItemsControl, Panel?> CreateGetItemsHostLambda()
{
var parameter = Expression.Parameter(type: typeof(ItemsControl));
return Expression.Lambda<Func<ItemsControl, Panel>>(
body: Expression.Property(
expression: parameter,
property: typeof(ItemsControl).GetProperty(
name: "ItemsHost",
bindingAttr: BindingFlags.NonPublic
| BindingFlags.GetProperty
| BindingFlags.Instance
)!
),
parameter
).Compile();
}
public static Panel? GetItemsPanel(this ItemsControl itemsControl)
=> getItemsHost.Value(itemsControl);
}

Mike Christiansen
- 1,104
- 2
- 13
- 30