【问题标题】:Custom renderer in UWP xamarinUWP 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 创建了我的代码。

【问题讨论】:

    标签: xamarin xamarin.forms xamarin.ios xamarin.uwp


    【解决方案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();
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2017-12-24
      • 2021-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-15
      • 2021-04-04
      • 2018-07-29
      相关资源
      最近更新 更多