大家好,我是本期的微软 MVP 实验室研究员——周豪。MAUI 中应用 Handler 体系来解决不同平台的原生控件实现,即对应的, 如果咱们想要创立控件,只须要创立基于不同平台的 Handler 即可。那么上面次要教大家如何通过创立 Handler(事件处理程序)来构建本人的控件。
上面,将通过创立一个进度条控件案例,来演示如何在 MAUI 我的项目中创立平台控件并且应用它。
假如控件蕴含根底的三项性能,进度条色彩(Foreground)、进度条以后值(Value)、进度条模式(Indeterminate)。
第一步
(申明控件类)
首先,创立 MyProgressBar 类,定义对应的依赖属性。
internal class MyProgressBar : View
{
public static readonly BindableProperty ForegroundProperty =
BindableProperty.Create(nameof(Foreground),
typeof(Color),
typeof(MyProgressBar),
Colors.Transparent);
public static readonly BindableProperty ValueProperty =
BindableProperty.Create(nameof(Value),
typeof(double),
typeof(MyProgressBar),
0.0);
public static readonly BindableProperty IndeterminateProperty =
BindableProperty.Create(nameof(Indeterminate),
typeof(bool),
typeof(MyProgressBar),
false);
public Color Foreground
{get { return (Color)GetValue(ForegroundProperty); }
set {SetValue(ForegroundProperty, value); }
}
public double Value
{get { return (double)GetValue(ValueProperty); }
set {SetValue(ValueProperty, value); }
}
public bool Indeterminate
{get { return (bool)GetValue(IndeterminateProperty); }
set {SetValue(IndeterminateProperty, value); }
}
}
第二步
创立规范处理程序
有了控件的规范属性定义之后,接下来就是定义规范的 Handler 处理程序,其中蕴含控件属性映射器及构造函数,如下所示:
partial class MyProgressBarHandler
{
public static PropertyMapper<MyProgressBar, MyProgressBarHandler> HorizontalProgressBarMapper = new
(ViewHandler.ViewMapper)
{[nameof(MyProgressBar.Value)] = MapValue,
[nameof(MyProgressBar.Foreground)] = MapForeground,
[nameof(MyProgressBar.Indeterminate)]= MapIndeterminate
};
public MyProgressBarHandler(PropertyMapper mapper)
: base(mapper)
{ }
public MyProgressBarHandler() : base(HorizontalProgressBarMapper)
{}}
第三步
创立平台处理程序
在属性映射器中,咱们能够很轻松看见对应了三个属性的事件处理程序,然而目前并没有定义它,这意味着你须要在不同平台下别离实现对应的三个事件处理程序,连忙在 Platforms > Android > Controls 下定义了一个 MyProgressBarHandler,如下所示:
接着继承于 ViewHandler 并且与原生安卓 ProgressBar 关联。
using Android.Widget;
partial class MyProgressBarHandler :
ViewHandler<MyProgressBar, ProgressBar>
{}
重写 CreateNativeView(这是创立本地控件最开始的中央)。
protected override ProgressBar CreateNativeView()
{return new ProgressBar(Context, null, Android.Resource.Attribute.ProgressBarStyleHorizontal)
{
Indeterminate = true,
Max = 10000,
};
}
紧接着, 实现三个事件处理程序办法, MapValue、MapForeground、MapIndeterminate。
static void MapValue(MyProgressBarHandler handler, MyProgressBar view)
{
var nativeView= handler?.NativeView;
nativeView.Progress = (int)(view.Value * Max);
}
static void MapForeground(MyProgressBarHandler handler, MyProgressBar view)
{UpdateForeground(handler?.NativeView, view.Foreground);
static void UpdateForeground(ProgressBar nativeProgressBar, Color color)
{if (color == null)
{
(nativeProgressBar.Indeterminate ? nativeProgressBar.IndeterminateDrawable :
nativeProgressBar.ProgressDrawable)?.ClearColorFilter();}
else
{var tintList = ColorStateList.ValueOf(color.ToNative());
if (nativeProgressBar.Indeterminate)
nativeProgressBar.IndeterminateTintList = tintList;
else
nativeProgressBar.ProgressTintList = tintList;
}
}
}
static void MapIndeterminate(MyProgressBarHandler handler, MyProgressBar view)
{
var nativeView= handler?.NativeView;
nativeView.Indeterminate = view.Indeterminate;
}
第四步
对应的实现 iOS 平台的 Handler 事件处理程序, 与上步骤雷同, 对于事件的解决细节则对应不同平台的逻辑解决
partial class MyProgressBarHandler :
ViewHandler<MyProgressBar, UIProgressView>
{protected override UIProgressView CreateNativeView()
{return new UIProgressView(UIProgressViewStyle.Default);
}
static void MapValue(MyProgressBarHandler handler, MyProgressBar view)
{
var nativeView = handler.NativeView;
nativeView.Progress = (float)view.Value;
}
static void MapForeground(MyProgressBarHandler handler, MyProgressBar view)
{
var nativeView = handler.NativeView;
nativeView.ProgressTintColor = view.Foreground?.ToNative();}
static void MapIndeterminate(MyProgressBarHandler handler, MyProgressBar view)
{//...}
}
第五步
关上 MauiProgram 文件, 增加 AddHandler
public static MauiApp CreateMauiApp()
{var builder = MauiApp.CreateBuilder();
builder.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
})
.ConfigureMauiHandlers(handler =>
{handler.AddHandler(typeof(MyProgressBar), typeof(MyProgressBarHandler));
});
return builder.Build();}
第六步
界面中, 别离申明 MAUI 原生控件与自定义控件
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MAUIRender.MainPage"
xmlns:my="clr-namespace:MAUIRender"
xmlns:ctor="clr-namespace:MAUIRender.Controls"
BackgroundColor="{DynamicResource SecondaryColor}">
<Grid>
<StackLayout>
<ProgressBar
Progress="30" ProgressColor="Red"/>
<ctor:MyProgressBar
Indeterminate="True"
Value="600" Foreground="Green" />
</StackLayout>
</Grid>
</ContentPage>
运行实际效果:
通过利用 Handler 来解决不同平台控件的行为,与控件自身解耦并且更加容易反对更多的平台。
微软最有价值专家(MVP)
微软最有价值专家是微软公司授予第三方技术专业人士的一个寰球奖项。28 年来,世界各地的技术社区领导者,因其在线上和线下的技术社区中分享专业知识和教训而取得此奖项。
MVP 是通过严格筛选的专家团队,他们代表着技术最精湛且最具智慧的人,是对社区投入极大的激情并乐于助人的专家。MVP 致力于通过演讲、论坛问答、创立网站、撰写博客、分享视频、开源我的项目、组织会议等形式来帮忙别人,并最大水平地帮忙微软技术社区用户应用 Microsoft 技术。
更多详情请登录官方网站:
https://mvp.microsoft.com/zh-cn