PlatformEffect 是 .NET MAUI 中用于为控件添加平台专属视觉或行为增强的轻量级声明式机制,无需重写渲染器,通过 RoutingEffect 抽象与各平台具体实现配合,在 XAML 或 C# 中一行代码即可启用,支持参数传递与自动生命周期管理。

在 .NET MAUI 中,PlatformEffect 是一种轻量、声明式的方式,用于为控件添加平台专属的视觉或行为增强(比如 Android 上的波纹点击效果、iOS 上的阴影偏移、Windows 上的圆角动画等),而无需重写整个渲染器。它比自定义渲染器更简单,适合只改样式或小交互的场景。
什么是 PlatformEffect?
PlatformEffect 是一种“附加效果”,可绑定到任意 MAUI 控件(如 Button、Label、Entry),在运行时注入平台原生逻辑。它基于 RoutingEffect(跨平台抽象) + 各平台具体实现(如 AndroidButtonRippleEffect),不侵入控件本身,也不影响共享逻辑。
关键特点:
- 不需修改控件类,用 XAML 或 C# 一行代码即可启用
- 各平台实现完全隔离,编译时/运行时互不影响
- 支持参数传递(通过
EffectControlProvider或绑定属性) - 生命周期由框架自动管理,无需手动释放
如何创建并使用一个 PlatformEffect
以给 Button 添加 Android 波纹效果为例(iOS 可配高亮色,Windows 可加悬停缩放):
1. 在共享项目中定义路由效果
public class RippleEffect : RoutingEffect
{
public RippleEffect() : base("MyCompany.RippleEffect")
{
}
}2. 在 Platforms/Android 目录下实现原生效果
using Android.Views;
using Microsoft.Maui.Controls.PlatformConfiguration.AndroidSpecific;
<p>[assembly: ResolutionGroupName("MyCompany")]
[assembly: ExportEffect(typeof(AndroidRippleEffect), "RippleEffect")]</p><p>namespace YourApp.Platforms.Android
{
public class AndroidRippleEffect : PlatformEffect
{
protected override void OnAttached()
{
var control = Control as Android.Widget.Button;
if (control != null)
{
// 设置波纹背景(需在 res/drawable 中准备 ripple.xml)
control.SetBackgroundResource(Resource.Drawable.ripple);
}
}</p><pre class="brush:php;toolbar:false;"> protected override void OnDetached() { }
}}
3. 在 XAML 中使用
<Button Text="点我">
<Button.Effects>
<local:RippleEffect />
</Button.Effects>
</Button>注意:local 是你共享项目中 RippleEffect 所在命名空间的 XML 前缀。
常见平台效果示例与适配要点
iOS:按钮按压阴影增强
- 在
Platforms/iOS中实现iOSButtonShadowEffect - 重写
OnAttached(),获取Control(即UIButton),设置Layer.ShadowOpacity = 0.3f和Layer.ShadowRadius = 2 - 建议监听
UIControl.EventTouchDown动态加深阴影,EventTouchUpInside恢复
Windows:Entry 获得焦点时轻微上浮
- 在
Platforms/Windows中获取Control(Microsoft.UI.Xaml.Controls.TextBox) - 用
VisualStateManager或直接操作RenderTransform实现 Y 方向平移动画 - 监听
GotFocus和LostFocus事件触发
注意事项与避坑指南
PlatformEffect 不是万能的,用错容易白忙活:
- 确保
ResolutionGroupName全局唯一,否则多个 Effect 冲突 - Android 上
Control可能为null(尤其在快速切换页面时),务必判空 - iOS 中
Control是UIView子类,但部分控件(如 Label)底层是UILabel,不支持某些 layer 属性,需确认类型 - Effect 无法访问 ViewModel 或绑定上下文,如需动态参数,改用
BindableProperty+ 自定义控件,或走 MessagingCenter 间接通信 - 调试时可在
OnAttached打日志,但注意 iOS 日志需连 Xcode 查看控制台
基本上就这些。PlatformEffect 是 MAUI 中最接地气的平台定制入口,不复杂但容易忽略细节。










