UWP xamarin 中的自定义渲染器
Posted
技术标签:
【中文标题】UWP xamarin 中的自定义渲染器【英文标题】:Custom renderer in UWP xamarin 【发布时间】:2020-03-16 05:20:15 【问题描述】:我有在ios
xamarin 表单上工作的自定义渲染代码,但我想要UWP
类似,
using System;
using MobileAssessment.Interface;
using MobileAssessment.iOS;
using MobileAssessment.Pages;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using iOSPlatform = Xamarin.Forms.Platform.iOS.Platform;
[assembly: Xamarin.Forms.Dependency(typeof(ILoadingPageServiceiOS))]
namespace MobileAssessment.iOS
public class ILoadingPageServiceiOS : ILodingPageService
private UIView _nativeView;
private bool _isInitialized;
public void ShowLoadingPage()
// check if the user has set the page or not
if (!_isInitialized)
InitLoadingPage(new LoadingIndicatorPage()); // set the default page
// showing the native loading page
UIApplication.SharedApplication.KeyWindow.AddSubview(_nativeView);
public void HideLoadingPage()
_nativeView.RemoveFromSuperview();
public void InitLoadingPage(ContentPage loadingIndicatorPage = null)
// check if the page parameter is available
if (loadingIndicatorPage != null)
// build the loading page with native base
loadingIndicatorPage.Parent = Xamarin.Forms.Application.Current.MainPage;
loadingIndicatorPage.Layout(new Rectangle(0, 0,
Xamarin.Forms.Application.Current.MainPage.Width,
Xamarin.Forms.Application.Current.MainPage.Height));
var renderer = loadingIndicatorPage.GetOrCreateRenderer();
_nativeView = renderer.NativeView;
_nativeView.BackgroundColor = UIColor.Black;
_nativeView.Alpha = (System.nfloat)0.7;
_isInitialized = true;
internal static class PlatformExtension
public static IVisualElementRenderer GetOrCreateRenderer(this VisualElement bindable)
var renderer = iOSPlatform.GetRenderer(bindable);
if (renderer == null)
renderer = iOSPlatform.CreateRenderer(bindable);
iOSPlatform.SetRenderer(bindable, renderer);
return renderer;
我已经为 UWP 尝试了以下代码,
using System;
using MobileAssessment.Interface;
using MobileAssessment.UWP;
using MobileAssessment.Pages;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.UWP;
using uwpPlatform = Xamarin.Forms.Platform.UWP.Platform;
[assembly: Xamarin.Forms.Dependency(typeof(ILoadingPageServiceRenderer))]
namespace MobileAssessment.UWP
public class ILoadingPageServiceRenderer : ILodingPageService
private View _nativeView;
private bool _isInitialized;
public void ShowLoadingPage()
// check if the user has set the page or not
if (!_isInitialized)
InitLoadingPage(new LoadingIndicatorPage()); // set the default page
// showing the native loading page
Application.SharedApplication.KeyWindow.AddSubview(_nativeView);
public void HideLoadingPage()
_nativeView.RemoveFromSuperview();
public void InitLoadingPage(ContentPage loadingIndicatorPage = null)
// check if the page parameter is available
if (loadingIndicatorPage != null)
// build the loading page with native base
loadingIndicatorPage.Parent = Xamarin.Forms.Application.Current.MainPage;
loadingIndicatorPage.Layout(new Rectangle(0, 0,
Xamarin.Forms.Application.Current.MainPage.Width,
Xamarin.Forms.Application.Current.MainPage.Height));
var renderer = loadingIndicatorPage.GetOrCreateRenderer();
_nativeView = renderer.NativeView;
_nativeView.BackgroundColor = Color.Black;
_nativeView.Alpha = (System.nfloat)0.7;
_isInitialized = true;
internal static class PlatformExtension
public static IVisualElementRenderer GetOrCreateRenderer(this VisualElement bindable)
var renderer = uwpPlatform.GetRenderer(bindable);
if (renderer == null)
renderer = iOSPlatform.CreateRenderer(bindable);
uwpPlatform.SetRenderer(bindable, renderer);
return renderer;
上面的活动指示器代码实际上来自https://github.com/UdaraAlwis/Xamarin-Playground/tree/master/XFLoadingPageService
但是论坛没有为 UWP 共享相同的解决方案,所以我为 windows 创建了我的代码。
【问题讨论】:
【参考方案1】:如果您正在寻找“全屏加载”样式,您还可以使用 ControlTemplate 并将其绑定到特定页面。
你可以这样做:
<Color x:Key="AccentColor">#ABDEBE</Color>
<ControlTemplate x:Key="FullScreenLoadingTemplate">
<AbsoluteLayout>
<ContentPresenter
AbsoluteLayout.LayoutFlags="All"
AbsoluteLayout.LayoutBounds="0, 0, 1, 1" />
<ContentView
AbsoluteLayout.LayoutFlags="All"
AbsoluteLayout.LayoutBounds="0, 0, 1, 1"
BackgroundColor="#80FFFFFF"
IsVisible="TemplateBinding BindingContext.IsBusy">
<ActivityIndicator
HorizontalOptions="Center"
IsRunning="TemplateBinding BindingContext.IsBusy"
VerticalOptions="Center"
Color="StaticResource AccentColor" />
</ContentView>
</AbsoluteLayout>
</ControlTemplate>
和页面绑定:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
ControlTemplate="StaticResource FullScreenLoadingTemplate"
Title="Binding Title"
IsBusy="Binding IsBusy"
x:Class="TestApp.Mobile.Pages.TestPage">... </ContentPage>
【讨论】:
不,我不想在每个屏幕上实现指示器。我想将指标创建为一项服务,并在我需要时在应用程序中使用它。基本上对于 iOS 实现,它在主应用程序 UIWindow 中添加(作为 UIView 的指示符)。但我不知道 UWP。【参考方案2】:毕竟我未能为 Window 平台编写相同的代码。所以我使用 Rg.Plugins.Popup.Pages 插件制作了解决方案。
应用全局加载器指示器 xaml 文件,
<?xml version="1.0" encoding="UTF-8"?>
<pages:PopupPage xmlns:pages="clr-namespace:Rg.Plugins.Popup.Pages;assembly=Rg.Plugins.Popup"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:telerikPrimitives="clr-namespace:Telerik.XamarinForms.Primitives;assembly=Telerik.XamarinForms.Primitives"
x:Class="MobileAssessment.Pages.AppGlobalLoader">
<ContentPage.Content>
<telerikPrimitives:RadBusyIndicator x:Name="BusyIndicator"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand"
AnimationContentHeightRequest="100"
AnimationContentWidthRequest="100"
AnimationType="Animation8"
AnimationContentColor="Teal"
IsBusy="True"
BackgroundColor="Black"
Opacity="0.7">
<telerikPrimitives:RadBusyIndicator.Content>
<StackLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" Opacity="0.7">
</StackLayout>
</telerikPrimitives:RadBusyIndicator.Content>
</telerikPrimitives:RadBusyIndicator>
</ContentPage.Content>
</pages:PopupPage>
应用全局加载器cs文件
using System;
using System.Collections.Generic;
using Rg.Plugins.Popup.Pages;
using Xamarin.Forms;
namespace MyApp.Pages
public partial class AppGlobalLoader : PopupPage
public AppGlobalLoader()
InitializeComponent();
我在基础导航器类中创建了两个方法显示和隐藏弹出窗口,
public async Task showLoader()
isPopupOpen = true;
AppGlobalLoader theAppGlobalLoader = new AppGlobalLoader();
await _Navigation?.PushPopupAsync(theAppGlobalLoader);
public async Task hideLoader()
if (isPopupOpen)
await _Navigation?.PopPopupAsync(true);
现在我在长时间运行的任务中使用上述方法,
async Task ExecuteAndSave()
if (ValidateFields())
await base.showLoader();
//Your long ruuning task dealing with server and saving stuff in database
await base.hideLoader();
await App.Current.MainPage.DisplayAlert("Successful", "Created", "Ok");
await ExecuteBackCommand();
【讨论】:
以上是关于UWP xamarin 中的自定义渲染器的主要内容,如果未能解决你的问题,请参考以下文章
使用 Xamarin Forms 在 UWP 中自定义进度条颜色
Xamarin 表单:UWP 和 Windows 8.1 中的自定义字体
[xamarin][uwp][custom renderer] 自定义渲染器 pcl 库未在发布模式下加载