zoukankan      html  css  js  c++  java
  • 基于Prism.Windows的UWP开发备忘

    以前做UWP开发都是使用MvvmLight,主要是简单易上手,同时也写了很多MvvmLight的开发系列文章:

    UWP开发必备以及常用知识点总结

    UWP开发之Mvvmlight实践九:基于MVVM的项目架构分享

    UWP开发之Mvvmlight实践八:为什么事件注销处理要写在OnNavigatingFrom中

    UWP开发之Mvvmlight实践七:如何查找设备(Mobile模拟器、实体手机、PC)中应用的Log等文件

    UWP开发之Mvvmlight实践六:MissingMetadataException解决办法(.Net Native下Default.rd.xml配置问题)

    UWP开发之Mvvmlight实践五:SuspensionManager中断挂起以及复原处理

    UWP开发之Mvvmlight实践四:{x:bind}和{Binding}区别详解

    UWP开发之Mvvmlight实践三:简单MVVM实例开发(图文详解付代码)

    UWP开发之Mvvmlight实践二:Mvvmlight的核心框架MVVM与MVC、MVP的区别(图文详解)

    UWP开发之Mvvmlight实践一:如何在项目中添加使用Mvvmlight(图文详解)

    出于开发效率考虑,以后打算都使用Prism或者Template10开发,其中很多的实现原理与MvvmLight相似。此次基于Prism.Windows完成的UWP应用虽然功能不是那么复杂,但是基本上用全了Prism的优良特性,特写下次篇做备忘。

    总结一:IOC控制反转容器

    目前只支持Unity,SimpleInjector,Autofac三个,相比MvvmCross或者Mvvmlight框架则选择更加灵活。

    使用方法(例如:Unity):

    1,App类继承于IOC对应的Application类。

    sealed partial class App : PrismUnityApplication
        {}

    2,依赖注入。(最好所有的注入都写在这个方法里面,后续的启动处理以及页面转移等可以立马使用。)

    protected override Task OnInitializeAsync(IActivatedEventArgs args)
    {
        Container.RegisterInstance<INavigationService>(NavigationService);
        Container.RegisterInstance<ISessionStateService>(SessionStateService);


        Container.RegisterType<ISettingService, SettingService>(new ContainerControlledLifetimeManager());

        return base.OnInitializeAsync(args);
    }

    3,调用。

    • App.cs内调用:

    await Container.Resolve<IAppStartupService>().CreateDataBaseAsync();

    • ViewModel内使用:
    private INavigationService _navigationService; 
    public HomePageViewModel(INavigationService navigationService)
    {     _navigationService = navigationService;
    }
     

    总结二:自动绑定

    自动绑定的命名规则:

    View名:HomePage

    ViewModel名:HomePageViewModel

    其次Views与ViewModels文件夹最好在同一个程序集下,然后View的头部添加如下两行代码,就可以自动绑定ViewModel。

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
    prism:ViewModelLocator.AutowireViewModel="True"
    Title="MainPage">
      <StackLayout HorizontalOptions="Center" VerticalOptions="Center">
        <Label Text="{Binding Title}" />
      </StackLayout>
    </ContentPage>

    如果View与ViewModel分层了,通过自定义ViewModelTypeResolver也可以实现自动绑定。

    ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver(
        viewType => {

            // 自由设置
            return Type.GetType("");
        });

    Prism.Mvvm下ViewModelLocationProvide.cs的默认设置如下:
            static Func<Type, Type> _defaultViewTypeToViewModelTypeResolver =

                viewType =>

                {

                    var viewName = viewType.FullName;

                    viewName = viewName.Replace(".Views.", ".ViewModels.");

                    var viewAssemblyName = viewType.GetTypeInfo().Assembly.FullName;

                    var suffix = viewName.EndsWith("View") ? "Model" : "ViewModel";

                    var viewModelName = String.Format(CultureInfo.InvariantCulture, "{0}{1}, {2}", viewName, suffix, viewAssemblyName);

                    return Type.GetType(viewModelName);

                };

    总结三:NavigationService

    全部接口:

    1. bool Navigate(string pageToken, object parameter);
    2. void GoBack();
    3. bool CanGoBack();
    4. void GoForward();
    5. bool CanGoForward();
    6. void ClearHistory();
    7. void RemoveFirstPage(string pageToken = null, object parameter = null);
    8. void RemoveLastPage(string pageToken = null, object parameter = null);
    9. void RemoveAllPages(string pageToken = null, object parameter = null);
    10. void RestoreSavedNavigation();
    11. void Suspending();

    有了它再也不用担心一些特殊的页面漂移问题。

    1,App.cs内部使用。(类以及包含NavigationService成员属性):

    // 启动页面表示
    NavigationService.Navigate("Home", null);
    

    2,ViewModel使用。

            private INavigationService _navigationService;
    
            public HomePageViewModel(INavigationService navigationService)
            {
                _navigationService = navigationService;
            }
     
    _navigationService.ClearHistory()等
     

    注意:

    由于10,11 的记录保存与复原都是使用DataContractSerializer序列化,所以页面漂移参数最好使用字符串或者数字。

    总结四:中断还原处理

    SessionStateService是类似SuspensionManager专门处理中断。

    1,App.cs内部设置

    依赖注入

    protected override Task OnInitializeAsync(IActivatedEventArgs args)
    {
        Container.RegisterInstance<ISessionStateService>(SessionStateService);

        return base.OnInitializeAsync(args);
    }

    类型注册

    protected override void OnRegisterKnownTypesForSerialization()
    {
    SessionStateService.RegisterKnownType(typeof(FavoriteInfo));
    SessionStateService.RegisterKnownType(typeof(ServerInfo));
     // 这个比较重要
    SessionStateService.RegisterKnownType(typeof(ObservableCollection<FavoriteInfo>));
    }

    2,ViewPage类型设置

    <prismMvvm:SessionStateAwarePage
     x:Class="PrismUnityApp1.Views.SettingPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:prismMvvm="using:Prism.Windows.Mvvm"
    prismMvvm:ViewModelLocator.AutoWireViewModel="True"
    
    mc:Ignorable="d">
     

    3,ViewModel中数据成员属性设置

     
    private ObservableCollection<FavoriteInfo> _favoriteFolders;
    [RestorableState]
    public ObservableCollection<FavoriteInfo> FavoriteFolders
    {     
      get     {         return _favoriteFolders;     }     
      set     {         SetProperty(ref _favoriteFolders, value);     }
    }
     

    4,.net native相关的Default.rd.xml设置

    <Type Name="PrismUnityApp1.DataModels.FavoriteInfo" 
    DataContractSerializer="Required Public" />        
    <Namespace Name="System.Collections.ObjectModel" >        
      <TypeInstantiation Name="ObservableCollection"  Arguments="PrismUnityApp1.DataModels.FavoriteInfo"
    DataContractSerializer="Required Public" />     
    </Namespace>
     

    总结五:ResourceLoader

     1,依赖注入。

    protected override Task OnInitializeAsync(IActivatedEventArgs args)

    {

    Container.RegisterInstance<IResourceLoader>(new ResourceLoaderAdapter(new ResourceLoader()));

    return base.OnInitializeAsync(args);

    }

    2,调用GetString()获取数据。

            public MenuViewModel(INavigationService navigationService, 

    IResourceLoader

     resourceLoader)
    
            {
    
                _navigationService = navigationService;
    
                Commands = new ObservableCollection<MenuItemViewModel>
    
                {
    
                    new MenuItemViewModel { DisplayName = resourceLoader.GetString("MainPageMenuItemDisplayName"), FontIcon = "ue15f", Command = new DelegateCommand(NavigateToMainPage, CanNavigateToMainPage) },
    
                    new MenuItemViewModel { DisplayName = resourceLoader.GetString("SecondPageMenuItemDisplayName"), FontIcon = "ue19f", Command = new DelegateCommand(NavigateToSecondPage, CanNavigateToSecondPage) }
    
                };
    
            }

    总结六:属性验证Validatable

    类似Asp.net MVC支持以下Validation:

    • Required
    • CreditCard
    • EmailAddress
    • PhoneNumber
    • Range
    • MinLength
    • MaxLenght
    • RegularExpression
    • Enumeration
    • URL

    使用方法:1,继承与ValidatableBindableBase

    public class Address : 

    ValidatableBindableBase

     

    2,成员设置:

    [Required(ErrorMessage = "Name is required.")]
    public string Name
    {
        get { return name; }
        set { SetProperty(ref name, value); }
    }
    
    [RegularExpression(@"[ABCD]d{2,5}", ErrorMessage="Location is Quadrant (A -> D) and Sector (2 -> 5 digits)")]
    public string Location
    {
        get { return location; }
        set { SetProperty(ref location, value); }
    }
     

    3,控件绑定

    <TextBox Text="{Binding Name, Mode=TwoWay}" Header="Name" /> 
    <TextBlock Text="{Binding Errors[Name][0]}" Foreground="Red" HorizontalAlignment="Right" />
     
    <ItemsControl x:Name="ErrorList" ItemsSource="{Binding Errors.Errors}" />
     

    备注:通过继承ValidationAttribute 可以自定义各种验证逻辑。

     

    总结七:菜单设置时机

    App.cs内部的CreateShell方法中设置:

            protected override UIElement CreateShell(Frame rootFrame)
            {
                var menuPage = Container.Resolve<MenuPage>();
                menuPage.NavigationFrame.Content = rootFrame;
                return menuPage;
            }
     

    总结八:数据库创建时机

    以前我们一般都是在OnLaunched方法内部添加如下代码实现:

    protected override void OnLaunched(LaunchActivatedEventArgs e)
            {
                Frame rootFrame = Window.Current.Content as Frame;
    
                // 不要在窗口已包含内容时重复应用程序初始化,
                // 只需确保窗口处于活动状态
                if (rootFrame == null)
                {
                    // 创建要充当导航上下文的框架,并导航到第一页
                    rootFrame = new Frame();
    
                    rootFrame.NavigationFailed += OnNavigationFailed;
    
                    if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
                    {
                        //TODO: 从之前挂起的应用程序加载状态
                    }
    
                    // 将框架放在当前窗口中
                    Window.Current.Content = rootFrame;
                }
    
                if (e.PrelaunchActivated == false)
                {
                    if (rootFrame.Content == null)
                    {
                        // 数据库创建
                        createDBAsync();
                        // 当导航堆栈尚未还原时,导航到第一页,
                        // 并通过将所需信息作为导航参数传入来配置
                        // 参数
                        rootFrame.Navigate(typeof(MainPage), e.Arguments);
                    }
                    // 确保当前窗口处于活动状态
                    Window.Current.Activate();
                }
            }
    
            Task createDBAsync()
            {
                // 略
                return Task.FromResult(true);
            }

    由于Prism封装了Application类,所以代码添加的位置也变了:

    protected override Task OnInitializeAsync(IActivatedEventArgs args)
            {
                createDBAsync();
                return base.OnInitializeAsync(args);
            }

    基本就这些东西,总结一下方便以后开发,同时也希望对园友们有帮助。

  • 相关阅读:
    sql语句清除mssql日志
    常用的一些webshell木马官方后门
    32个触发事件XSS语句的总结
    XSS的高级利用部分总结 -蠕虫
    IIS7 Appcmd.exe 使用
    PHP Execute Command Bypass Disable_functions
    仿5173游戏交易平台系统SQL注入(可直接脱裤)+Getshell
    win95+ie3-win10+ie11 浏览器执行漏洞
    SQL 、NoSQL数据库教程
    Pytorch快速入门及在线体验
  • 原文地址:https://www.cnblogs.com/lixiaobin/p/PrismWindowsUwpDev.html
Copyright © 2011-2022 走看看