天天看點

Prism 開發之四 ViewModelLocator

1、概況     

  Prism具有附加屬性,當設定為調用類中的方法來解析視圖模型以進行檢視,然後将視圖的資料上下文設定為該視圖模型的執行個體時。

使用以下附加屬性。設定選擇退出和明确選擇加入的價值。

AutoWireViewModel

False

True

<Window x:Class="Demo.Views.MainWindow" ... xmlns:prism="http://prismlibrary.com/" prism:ViewModelLocator.AutoWireViewModel="False">      

要找到視圖模型,如果無法使用此方法解決 ViewModel,則傳回到基于慣例的方法來解決正确的視圖模型類型。

containerRegistry.Register<Services.ICustomerStore, Services.DbCustomerStore>();      

本公約假定:

  • 視圖模組與視圖類型處于相同的元件中
  • 視圖模組位于兒童命名空間中

    .ViewModels

  • 視圖位于兒童命名空間中

    .Views

  • 視圖模型名稱與視圖名稱相對應,并以"檢視模型"結尾。

  可以在Prism中. 核心Nuget 包的命名空間中找到。可以在平台特定包(Prism.WPF,棱鏡.形式)的命名空間中找到 NuGet 包。

ViewModelLocationProvider

Prism.Mvvm

ViewModelLocator

Prism.Mvvm

2、更改命名公約

  如果您的申請未遵循預設命名慣例,您可以更改該公約以滿足您的申請要求。該類提供了一種靜态方法,可用于提供您自己的約定,以便關聯視圖以檢視模型。

SetDefaultViewTypeToViewModelTypeResolver

要更改命名約定,要在類中覆寫該方法。然後在方法中提供您的自定義命名慣例邏輯。

ViewModelLocator

ConfigureViewModelLocator

App.xaml.cs

ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver

protected override void ConfigureViewModelLocator()
{
    base.ConfigureViewModelLocator();

    ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver((viewType) =>
    {
        var viewName = viewType.FullName.Replace(".ViewModels.", ".CustomNamespace.");
        var viewAssemblyName = viewType.GetTypeInfo().Assembly.FullName;
        var viewModelName = $"{viewName}ViewModel, {viewAssemblyName}";
        return Type.GetType(viewModelName);
    });
}      
3、自定義視圖模型注冊           

  可能有以下情況表明,您的應用遵循預設命名慣例,但您有許多視圖模組不符合該公約。您可以使用該方法直接注冊 ViewModel 的映射,而不是嘗試自定義命名會議邏輯以有條件地滿足您的所有命名要求。

ViewModelLocatorViewModelLocatorViewModelLocationProvider.Register      

  以下示例顯示了在稱為"檢視"和"檢視模型"之間建立映射的各種方法。

MainWindow

CustomViewModel

  類型 / 類型

ViewModelLocationProvider.Register(typeof(MainWindow).ToString(), typeof(CustomViewModel));
           

  類型/ 工廠

ViewModelLocationProvider.Register(typeof(MainWindow).ToString(), () => Container.Resolve<CustomViewModel>());
           

  通用工廠

ViewModelLocationProvider.Register<MainWindow>(() => Container.Resolve<CustomViewModel>());
           

  通用類型

ViewModelLocationProvider.Register<MainWindow, CustomViewModel>();
           

  注意

  直接在 ViewModels 上注冊比依賴預設命名約定要快。這是因為命名公約需要使用反射,而自定義映射直接提供類型到 。

ViewModelLocator

ViewModelLocator

重要

  參數必須是視圖類型()的完全合格名稱。否則映射将失敗。

viewTypeName

Type.ToString()

4、控制如何解決視圖模型

protected override void ConfigureViewModelLocator() { 

base.ConfigureViewModelLocator(); 
ViewModelLocationProvider.SetDefaultViewModelFactory(viewModelType) => {
return MyAwesomeNewContainer.Resolve(viewModelType); 
});
 }      
這是一個示例,說明您可以如何檢查"檢視模型"建立的視圖類型,并執行邏輯來控制"視圖模型"的建立方式。      
protected override void ConfigureViewModelLocator() {
base.ConfigureViewModelLocator(); 
  ViewModelLocationProvider.SetDefaultViewModelFactory((view, viewModelType) => {
switch (view) {
   case Window window: //your logic break; case UserControl userControl: //your logic break; } return MyAwesomeNewContainer.Resolve(someNewType); }); 
}