UWP xamarin 中的自定义渲染器

Custom renderer in UWP xamarin

我有在 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

得到的activity指标

但是论坛没有为 UWP 共享相同的解决方案,所以我为 windows 创建了我的代码。

如果您正在寻找 "FullScreen loading" 样式,您还可以使用 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>

毕竟我未能为 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>

App全局加载器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();
        }
    }
}

我在基本导航器中创建了两种显示和隐藏弹出窗口的方法class,

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