• MvvmLight


    这里先鼓舞下士气,ViewModelLocator很简单,甚至可以去掉,它不是Mvvm必须的。在初学Mvvm时,一般都是使用NuGet安装
    MvvmLight框架,总是会带上那么一个ViewModelLocator,并且还加入到了全局资源中,到底是干吗的?

    public class ViewModelLocator
        {
            /// <summary>
            /// Initializes a new instance of the ViewModelLocator class.
            /// </summary>
            public ViewModelLocator()
            {
                ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
    
                SimpleIoc.Default.Register<AppViewModel>();
            }
    
            public AppViewModel Main
            {
                get
                {
                    return ServiceLocator.Current.GetInstance<AppViewModel>();
                }
            }
    
            public static void Cleanup()
            {
                // TODO Clear the ViewModels
            }
        }

    上面就是一个具有基本功能的试图模型定位器,它的作用就是访问ViewModel,你想用哪个ViewModel就在这里找,构造函数中首先注册一个AppViewModel类型
    然后通过Main属性暴露出来,当我们访问Main属性的时候,就会把AppViewModel的实例返回,注意SimpleIoc默认是
    单实例的,返回的是同一个Main

    注意:在构造该对象时,我们将MvvmLight自带的SimpleIoc容器指定作为默认服务提供者,
    这里为什么要使用ServiceLocator又将SimpleIoc容器包裹一层,
    其实在运行时,我们直接使用SimpleIoc也是没有问题的,
    这里主要是考虑到一个设计时的显示效果,
    设计时就能在设计窗口看到ViewModel中的数据。

    接下来我们看如何使用ViewModelLocator,在使用NuGet安装MvvmLight时,会自动给我们的App.xaml加入一个Resource

    <Application x:Class="MvvmDemo.App" 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" 
                 d1p1:Ignorable="d" 
                 xmlns:d1p1="http://schemas.openxmlformats.org/markup-compatibility/2006"
                 xmlns:mvvmDemo="clr-namespace:MvvmDemo" StartupUri="Views/AppView.xaml">
      <Application.Resources>
        <mvvmDemo:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
      </Application.Resources>
    </Application>    

    ViewModelLocator就作为一个全局资源引用到了程序中,注意在App类初始化时,就会去初始化ViewModelLocator。
    这样我们在界面上就可以使用全局资源找到对应的ViewModel。

     <Window x:Class="MvvmDemo.Views.AppView"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:validationRules="clr-namespace:MvvmDemo.ValidationRules"
            xmlns:converter="clr-namespace:MvvmDemo.Converter"
            xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
            xmlns:command="http://www.galasoft.ch/mvvmlight"
            Title="AppView" Height="300" Width="300" DataContext="{Binding Source={StaticResource Locator},Path=Main}">
     </Window>
     

    这里将AppView的DataContext设置为全局静态资源中的Main,此时,在VS的可视化窗口中,就会看到数据已经绑定上。

    总结一下:这里我们首先有一个ViewModelLocator,然后又是资源,又是Binding,其实目的就是为了在设计时,能够
    将数据友好的显示,即时看到效果。我们完全可以把这个ViewModelLocator删除,在AppView的构造函数中,将DataContext
    设置为AppViewModel

     public AppView()
            {
                this.DataContext=new AppViewModel();
            }

    当然呢,这种做法很粗鲁,设计时也不会看到绑定的数据。ViewModelLocator的作用就是这么点,也不是很复杂。

    SimpleIoc

    这个需要了解一下IOC是什么,这儿有一篇很好的文章,也很生动。
    IOC的内容很大,在Mvvm中自带了一个Ioc容器,SimpleIoc,之所以叫SimpleIoc,是因为它的确很简单,仅仅是作为
    对象容器来使用的。例如在设计时的数据可视化效果中,向View的DataContext提供对应的ViewModel。
    实际开发中,我们会使用更加灵活的Ioc,例如:MEF,园子里有很不错的教程

    ((((((((((下面是一篇转自知乎的文章,解释的也很详细)))))))))))))))))))))))))

    我不是程序员只是个软件测试,业余对WPF C#感兴趣也自学了点,正好mvvmlight也自学过,半吊子我也不能回答的很专业,请包涵。希望下面高人能有更好的解释。
    SimpleIoc 是一个简单依赖注入容器, 至于什么是依赖注入可以在百度经验找到很通俗的解释。微软还有自己的类似的框架叫MEF,两者用起来异曲同工,甚至我觉得MEF更简洁强大。

    你 查看SimpoleIoc的定义就会知道SimpleIoc其实实现了IServiceLocator,SimpleIoc就是一个 IServiceLocator。而ServiceLocator这个是一个静态类是用来获取当前使用中的IServiceLocator的。
    SimpleIoc的作用是,所有通过SimpleIoc的GetInstance方法创建的实例,都会自动从容器里自动组装。
    自动组装什么意思看下面例子。

    比方说你有个服务MyDataService,这个服务是用来获取数据的,而这个服务是实现自IDataService这个接口。
    然后你有个MainViewModel,他的构造函数是 MainViewModel(IDataService dataSevice)

    一般情况下你要 创建MainViewModel的实例你还得手动把一个具体的IDataService也创建好传入。
    而用SimpleIoc帮你组装的话你就不需要这么做了。

    你将实现了接口的服务向下面这样注册到SimpleIoc里。
    SimpleIoc.Default.Register<IDataService, MyDataService>();
    然后将MainViewModel也注册到SimpleIoc里。
    SimpleIoc.Default.Register<MainViewModel>();

    然 后通过 SimpleIoc.Default.GetInstance<MainViewModel>() 就可以直接创建一个实例,SimpleIoc在发现 MainViewModel的构造函数有参数的时候会自动去找所有注册到SimpleIoc的类型看哪个符合这个参数类型,如果之前已经创建过这个类型就 直接拿缓存传入,如果没有就立刻创建一个实例传入并缓存。这就是注入,你的ViewModel需要什么样的具体服务是Simploc在帮你创建传入的,这 样你的ViewModel就不依赖具体的Service了。

    我之前还翻译了StackOverFollow上的一个关于SimpleIoc用法的提问,贴出来希望能帮到你。
    SimpleIoc crib sheet:
    1) You register all your interfaces and objects in the ViewModelLocator
    你需要将所有的接口和对象注册到ViewModelLocator
    class ViewModelLocator
    {
    static ViewModelLocator()
    {
    ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
    if (ViewModelBase.IsInDesignModeStatic)
    {
    SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
    }
    else
    {
    SimpleIoc.Default.Register<IDataService, DataService>();
    }
    SimpleIoc.Default.Register<MainViewModel>();
    SimpleIoc.Default.Register<SecondViewModel>();
    }
    public MainViewModel Main
    {
    get
    {
    return ServiceLocator.Current.GetInstance<MainViewModel>();
    }
    }
    }
    2) Every object is a singleton by default. To resolve an object so that it's not a singleton you need to pass a unique value to the GetInstance call:
    默认Ioc Getinstance获取的所有的对象都是单例的。如果想要每次getinstance都是独一无二的对象那么你需要在GetInstance的时候传 入唯一的值来标志这个对象,也就是String key,你可以使用Guid创建这个唯一的标识,Guid.NewGuid()每次调用都会产生唯一的值。
    SimpleIoc.Default.GetInstance<MainViewModel>(Guid.NewGuid().ToString());
    3) To register a class against an interface:
    将一个类注册到对应接口
    SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
    4) To register a concrete object against an interface:
    将一个具体对象注册到对应接口
    SimpleIoc.Default.Register<IDataService>(myObject);
    5) To register a concrete type:
    注册一个具体的类
    SimpleIoc.Default.Register<MainViewModel>();
    6) To resolve an object from an interface:
    根据接口返回对象
    SimpleIoc.Default.GetInstance<IDataService>();
    7) To resolve an object directly (does buildup and dependency resolution):
    返回一个具体类对象,并依赖注入。
    注: 例如 MainViewModel的构造函数是MainViewModel(IDataService dataservice),那么这次GetInstance<MainViewModel>()会同时从Ioc里将 MainViewModel依赖的具体IDataService传进去。
    SimpleIoc.Default.GetInstance<MainViewModel>();
    8) MVVM makes doing design-time data really easy:
    用MVVM做设计时数据非常简单
    if (ViewModelBase.IsInDesignModeStatic)
    {
    SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
    }
    else
    {
    SimpleIoc.Default.Register<IDataService, DataService>();
    }
    If you're in design-time mode it will automatically register your design-time services, making it really easy to have data in your viewmodels and views when working in the VS designer.
    如果你在设计时模式,ioc会自动注册设计时服务,这样你的viewmodels在未编译的状态下就填充了设计时数据,可以在设计器上直接观察。
    Hope this helps.
    希望这些能帮到你。
    https://www.zhihu.com/question/36338698
    来自 <c# - how to use MVVMLight SimpleIoc?>

  • 相关阅读:
    jquery取iframe中元素
    jquery 复选框全选/全不选切换 普通DOM元素点击选中/取消选中切换
    css横向 弹性盒子布局的一些属性
    css3 html5画心
    herf 和 src 的区别
    AngularJS bind
    I18n国际化
    jqgrid获取数据条数
    @ModelAttribute设置request、response、session对象
    js浏览器判断函数
  • 原文地址:https://www.cnblogs.com/maanshancss/p/5794770.html
Copyright © 2020-2023  润新知