锐英源软件
第一信赖

精通

英语

开源

擅长

开发

培训

胸怀四海 

第一信赖

当前位置:锐英源 / 开源技术 / WPF / WPF的MVVM自动定位ViewModel实例
服务方向
人工智能数据处理
人工智能培训
kaldi数据准备
小语种语音识别
语音识别标注
语音识别系统
语音识别转文字
kaldi开发技术服务
软件开发
运动控制卡上位机
机械加工软件
软件开发培训
Java 安卓移动开发
VC++
C#软件
汇编和破解
驱动开发
联系方式
固话:0371-63888850
手机:138-0381-0136
Q Q:396806883
微信:ryysoft

锐英源精品原创,禁止全文或局部转载,禁止任何形式的非法使用,侵权必究。点名“简易百科”和闲暇巴盗用锐英源原创内容。

WPF的MVVM自动定位ViewModel实例


WPF的MVVM中的ViewModel负责View的数据组织,一般是一个View对应一个ViewModel,但是如果能灵活自动定位,就会能解决一些奇怪的问题,比如通用的View对应多个ViewModel,所以有兴趣的朋友请认真看本篇翻译。

提示下:看不懂codeproject,找锐英源。

介绍

ViewModels我将在 MVVM 模式的实例化中介绍一个小技巧。

有时,我们在 WPF 小型解决方案中工作,其中通常不需要ViewModelLocator类作为ViewModels类生成器,因为我们不需要保存ViewModels引用。我们不会担心为ViewModelLocator类提供食物,我们将立即部署我们的ViewModels类。这与单元测试和绑定引擎完美契合。

背景

我们会有两种情况:

  • Viewname 和ViewModelname 有一个等价的名字:
  • View名称和名称ViewModel没有等效名称:

等效名称(视图和视图模型)

在这种情况下,只需在视图中配置一个属性:

XML
<Window x:Class="AutoMVVMLocator.Example1View"
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:local="clr-namespace:AutoMVVMLocator"
local:MLMVVM.IsAutomaticLocator="True"
mc:Ignorable="d"
Title="Example1View" Height="300" Width="300">

重要的部分是:

XML
local:MLMVVM.IsAutomaticLocator = "True"

在这个例子中,视图Example1View自动实例化一个Example1ViewModel作为DataContext对象。

不等效名称(视图和视图模型)

在这种情况下,我们需要指定另一个具有ViewModel类名称的属性。

XML
<Window x:Class="AutoMVVMLocator.Example2Window"
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:local="clr-namespace:AutoMVVMLocator"
local:MLMVVM.ViewModelClassName="Example2ViewModel"
local:MLMVVM.IsAutomaticLocator="True"
mc:Ignorable="d"
Title="Example2Window" Height="300" Width="396.546">

重要的部分:

XML
local:MLMVVM.ViewModelClassName = "Example2ViewModel"
local:MLMVVM.IsAutomaticLocator = "True"

注意:属性ViewModelClassName必须放在首位。

在这个例子中,视图Example2Window自动实例化一个Example2ViewModel作为DataContext对象。

MLMVVM 类

这是一个非常简单的类。它有两种AtachProperties和两种private方法。

这些attachproperties是以前配置的属性:

  • IsAutomaticLocator - 激活自动实例ViewModels类。
  • ViewModelClassName - 显示ViewModel要实例化的类名。如果您的ViewModelClass姓名与姓名等价,View则不需要其属性。
C#
public static bool GetIsAutomaticLocator(DependencyObject obj)
{
    return (bool)obj.GetValue(IsAutomaticLocatorProperty);
}

public static void SetIsAutomaticLocator(DependencyObject obj, bool value)
{
    obj.SetValue(IsAutomaticLocatorProperty, value);
}

public static readonly DependencyProperty IsAutomaticLocatorProperty =
    DependencyProperty.RegisterAttached("IsAutomaticLocator", 
    typeof(bool), typeof(MLMVVM), new PropertyMetadata(false, IsAutomaticLocatorChanged));

private static void IsAutomaticLocatorChanged
(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var callOwner = d as FrameworkElement;

    var className = GetViewModelClassName(d);

    var userControl = GetInstanceOf(callOwner.GetType(), className);

    callOwner.DataContext = userControl;
}


public static string GetViewModelClassName(DependencyObject obj)
{
    return (string)obj.GetValue(ViewModelClassNameProperty);
}

public static void SetViewModelClassName(DependencyObject obj, string value)
{
    obj.SetValue(ViewModelClassNameProperty, value);
}


public static readonly DependencyProperty ViewModelClassNameProperty =

    DependencyProperty.RegisterAttached("ViewModelClassName", 
    typeof(string), typeof(MLMVVM), new PropertyMetadata(null));

这两个private方法包含一个动态实例引擎:

C#
private static object GetInstanceOf(Type dependencyPropertyType, string className)
{
    var assembly = dependencyPropertyType.Assembly;

    var assemblyTypes = assembly.GetTypes();

    var classNameDef = GetClassName(dependencyPropertyType, className);

    var userControlType = assemblyTypes.FirstOrDefault(a => a.Name.Contains(classNameDef));

    if (userControlType == null) 
    throw new ArgumentException($"Not exist a type 
    {classNameDef} in the assembly {assembly.FullName}");

    var resultado = Activator.CreateInstance(userControlType);

    return resultado;
}

private static string GetClassName(Type dependencyPropertyType, string className)

{
    if (string.IsNullOrWhiteSpace(className)) 
    return $"{dependencyPropertyType.Name}Model";

    return className;
}

限制

如果你在做一个伟大的项目,或者你需要恢复ViewModels实例的引用,你必须使用一个经典的ViewModelLocator类。

 

注:作者其实扩展了框架,用了DependencyObject,这些框架功能在常见的mvvm框架里都有,但本文对于学习框架有价值。

友情链接
版权所有 Copyright(c)2004-2021 锐英源软件
公司注册号:410105000449586 豫ICP备08007559号 最佳分辨率 1024*768
地址:郑州大学北校区院(文化路97号院)内