设为首页 收藏本站
查看: 857|回复: 0

[经验分享] 基于Prism.Windows的UWP开发备忘

[复制链接]

尚未签到

发表于 2017-6-27 16:44:26 | 显示全部楼层 |阅读模式
  以前做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
  全部接口:


  • bool Navigate(string pageToken, object parameter);
  • void GoBack();
  • bool CanGoBack();
  • void GoForward();
  • bool CanGoForward();
  • void ClearHistory();
  • void RemoveFirstPage(string pageToken = null, object parameter = null);
  • void RemoveLastPage(string pageToken = null, object parameter = null);
  • void RemoveAllPages(string pageToken = null, object parameter = null);
  • void RestoreSavedNavigation();
  • 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);
}
  基本就这些东西,总结一下方便以后开发,同时也希望对园友们有帮助。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-388837-1-1.html 上篇帖子: 转 Windows+VS2013爆详细Caffe编译安装教程 下篇帖子: Windows服务器安全加固实战(Windows Server 2008 R2和Windows Server 2012)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表