开发者

Can I access ItemsHost of ItemsControl using reflection?

开发者 https://www.devze.com 2023-02-11 08:14 出处:网络
I\'m creating custom ItemsControl that is derived from DataGrid. I need to a开发者_如何学Pythonccess ItemsHost that is the Panel that actually holds rows of DataGrid. I have seen som ugly tricks to do

I'm creating custom ItemsControl that is derived from DataGrid. I need to a开发者_如何学Pythonccess 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 ?


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.


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

}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号