You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET8中如何访问控件隐式样式?SetterSpecificity权限问题

问题

自定义控件需要在内部获取其隐式设置的样式,但受限于SetterSpecificity的访问权限,无法直接实现。此前在.NET7中通过反射方式实现了需求,但升级到.NET8后该方法失效,出现与SetterSpecificity相关的访问问题。

.NET7中可用的实现代码

XAML页面代码

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:MauiApp1"
             x:Class="MauiApp1.MainPage">

    <ContentPage.Resources>
        <Style TargetType="local:CustomButton">
            <Setter Property="HorizontalOptions" Value="Center" />
            <Setter Property="VerticalOptions" Value="Center" />
            <Setter Property="BackgroundColor" Value="Bisque" />
            <Setter Property="FontSize" Value="18" />
        </Style>
    </ContentPage.Resources>

    <local:CustomButton
                Text="Hello World!!"
                FontSize="18"
                HorizontalOptions="Center" />

</ContentPage>

C#自定义控件代码

using Microsoft.Maui.Controls;
using System.Reflection;

namespace MauiApp1
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
        }
       
    }

    public class CustomButton : Button
    {
        public CustomButton()
        {
            this.Clicked += CustomButton_Clicked;
        }

        private void CustomButton_Clicked(object sender, EventArgs e)
        {
            var dynamicResources = (Dictionary<BindableProperty, string>)typeof(Element)?.GetRuntimeProperties()?.FirstOrDefault(x => x.Name == "DynamicResources")?.GetValue(this);
            var key = dynamicResources?.Keys.FirstOrDefault();
            var style = (Style)this.GetValue(key);
        }
    }
}

.NET8兼容的解决方案

由于.NET8对内部API的访问限制更严格,反射方式不再适用。可以通过遍历控件的资源层级,合法获取隐式样式:

using Microsoft.Maui.Controls;

namespace MauiApp1
{
    public class CustomButton : Button
    {
        public CustomButton()
        {
            Clicked += CustomButton_Clicked;
        }

        private void CustomButton_Clicked(object sender, EventArgs e)
        {
            var implicitStyle = GetImplicitStyleForControl();
            // 在这里使用获取到的隐式样式
        }

        private Style GetImplicitStyleForControl()
        {
            Element currentElement = this;
            // 从控件自身向上遍历父元素的资源字典
            while (currentElement != null)
            {
                if (currentElement.Resources.TryGetValue(typeof(CustomButton), out var resource) && resource is Style style)
                {
                    return style;
                }
                currentElement = currentElement.Parent;
            }
            // 最后检查应用级资源
            if (Application.Current?.Resources.TryGetValue(typeof(CustomButton), out var appResource) == true && appResource is Style appStyle)
            {
                return appStyle;
            }
            return null;
        }
    }
}

说明

该方法通过遍历控件的父级资源链(从自身到页面再到应用),查找匹配自定义控件类型的隐式样式,完全依赖公开API,不存在内部成员访问权限问题,同时兼容.NET7和.NET8版本。

内容的提问来源于stack exchange,提问作者Tamizh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 23:55:21