C# WPF MVVM开发框架Caliburn.Micro 自定义Conventions⑩
處理自定義約定
雖然ViewLocator和ViewModelLocator類通過提供對每個類的NameTransformer實例的公共訪問來支持非標準約定,但對于那些不熟悉正則表達式語法的人來說,添加基于正則表達式的新名稱轉換規則可能是一項艱巨的任務。此外,由于NameTransformer設計用于執行通用名稱轉換,因此它不允許單獨定制名稱和名稱空間轉換。換句話說,沒有簡單的方法可以在維護名稱空間的標準轉換的同時添加對自定義視圖名稱后綴的支持,也沒有簡單的方法可以在維護類型名稱的標準轉換的同時更改名稱空間轉換。認識到這些局限性,我們為每個定位器類添加了可配置性和幾個高級方法。這些新特性允許為常見用例構建自定義轉換規則,而無需了解正則表達式。此外,這些方法是領域感知的(即它們考慮了名稱空間和類型名稱的概念),而不是面向泛型名稱轉換。
術語
在介紹定位器類的這些新方法之前,最好先討論一下術語。
名稱轉換是一個通用術語,用于描述如何進行類型解析。類型的完全限定名作為源,然后“轉換”為輸出類型的名稱。在最低級別,NameTransformer類負責此操作,并使用基于正則表達式的“轉換規則”執行轉換。
類型映射是一個術語,用于描述添加到定位器類中的新功能。創建類型映射被認為是更高級別的操作,因為類型映射考慮類型解析的兩個方面:解析類型的名稱和解析類型的命名空間。盡管類型映射最終被表示為NameTransformer的轉換規則,但是創建類型映射的方法除了更特定于域之外,還可以使您不必理解正則表達式。
類型映射的配置
這兩個定位器類都可以通過調用新的ConfigureTypeMappings()方法進行配置,該方法將TypeMappingConfiguration類的實例作為參數。
類型映射配置類
此類具有各種屬性,其值用作定位器類配置各種高級類型映射方法行為所需的全局設置。
Properties
DefaultSubNamespaceForViews:包含應用程序視圖的子名稱空間(即命名空間“MyProject.Views”中的“視圖”)。此值用于為ViewModels創建具有子名稱空間的默認映射。默認值為“視圖”。
DefaultSubNamespaceForViewModels:包含應用程序的ViewModels的子命名空間(即命名空間“MyProject.ViewModels”中的“ViewModels”)。此值用于為視圖創建具有子名稱空間的默認映射。默認值為“ViewModels”。
UseNameSuffixesInMappings:指示映射是否應考慮類型名稱中的名稱后綴以區分視圖和視圖模型的標志。如果可以通過命名空間或子命名空間空間來區分視圖和ViewModels,則可以將此值設置為false。默認值為true。
NameFormat:用于使用基名稱(或實體名稱)和視圖或視圖模型后綴構造類型名稱的格式字符串。格式項目如下:
{0}:基名稱
{1} :名稱后綴
由于只有兩個參數將與指定的格式字符串一起使用,NameFormat可以包含上面列出的格式項的任何組合,但不能再包含任何組合(即{2}、{3}等)。默認值為“{0}{1}”(即<basename><suffix>)。
INCLUDEVIEWUFFIXIVIEWMODELNAME:指示映射是否應將“頁面”或“表單”等名稱后綴作為伴生視圖模型名稱的一部分的標志(例如CustomerPageViewModel與CustomerServiceWModel或CustomerPerformViewModel與CustomerServiceWModel)。請注意,按照慣例,無論此屬性的值如何,如果視圖后綴是ViewModel后綴的一部分,則假定忽略視圖后綴(即CustomerViewModel而不是CustomerViewModel)。默認值為true。
ViewSuffixList:在配置期間為其創建默認類型映射的視圖后綴列表。默認值為“視圖”和“頁面”。
ViewModelSuffix:用于所有類型映射的ViewSuffix,包括配置期間添加的默認類型映射以及配置之后添加的自定義類型映射。默認值為“ViewModel”。
ViewLocator.ConfigureTypeMapping(), ViewModelLocator.ConfigureTypeMapping() Methods
此方法配置或重新配置定位器類添加類型映射的方式。
public static void ConfigureTypeMapping(TypeMappingConfiguration config)config參數是一個配置對象,其屬性值用作配置類型映射的定位器類的設置。
locator類使用TypeMappingConfiguration類的默認屬性值在內部調用此方法。
每次調用此方法時,都會清除現有的名稱轉換規則,并自動添加新的默認類型映射。
配置對象的設置全局應用于在配置時自動添加的默認類型映射和配置后添加的任何類型映射。例如,如果對NameFormat進行了自定義,以指定將名稱后綴放在基名稱之前的命名約定,從而將名稱后綴轉換為前綴(例如ViewCustomer和ViewModelCustomer),則此約定將用作對添加類型映射的方法的任何后續調用的標準類型命名約定
//Override the default subnamespaces var config = new TypeMappingConfiguration {DefaultSubNamespaceForViewModels = "MyViewModels",DefaultSubNamespaceForViews = "MyViews" };ViewLocator.ConfigureTypeMappings(config); ViewModelLocator.ConfigureTypeMappings(config);//Resolves: //MyProject.MyViewModels.CustomerViewModel -> MyProject.MyViews.CustomerView //MyProject.MyViewModels.CustomerPageViewModel -> MyProject.MyViews.CustomerPage //MyProject.MyViews.CustomerView -> MyProject.MyViewModels.CustomerViewModel //MyProject.MyViews.CustomerPage -> MyProject.MyViewModels.CustomerPageViewModel//Change ViewModel naming convention to always exclude View suffix var config = new TypeMappingConfiguration {DefaultSubNamespaceForViewModels = "MyViewModels",DefaultSubNamespaceForViews = "MyViews",IncludeViewSuffixInViewModelNames = false };ViewLocator.ConfigureTypeMappings(config); ViewModelLocator.ConfigureTypeMappings(config);//Resolves: //MyProject.MyViewModels.CustomerViewModel -> MyProject.MyViews.CustomerPage, MyProject.MyViews.CustomerView //MyProject.MyViews.CustomerView -> MyProject.MyViewModels.CustomerViewModel //MyProject.MyViews.CustomerPage -> MyProject.MyViewModels.CustomerViewModel//Change naming conventions to place name suffixes before the base name (i.e. name prefix) var config = new TypeMappingConfiguration {NameFormat = "{1}{0}",IncludeViewSuffixInViewModelNames = false };ViewLocator.ConfigureTypeMappings(config); ViewModelLocator.ConfigureTypeMappings(config);//Resolves: //MyProject.ViewModels.ViewModelCustomer -> MyProject.Views.PageCustomer, MyProject.Views.ViewCustomer //MyProject.Views.ViewCustomer -> MyProject.ViewModels.ViewModelCustomer //MyProject.Views.PageCustomer -> MyProject.ViewModels.ViewModelCustomer//Change naming conventions to omit name suffixes altogether (i.e. distinguish View and ViewModel types by namespace alone) var config = new TypeMappingConfiguration {UseNameSuffixesInMappings = false };ViewLocator.ConfigureTypeMappings(config); ViewModelLocator.ConfigureTypeMappings(config);//Resolves: //MyProject.ViewModels.Customer -> MyProject.Views.Customer //MyProject.Views.Customer -> MyProject.ViewModels.Customer//Configure for Spanish language and semantics var config = new TypeMappingConfiguration() {DefaultSubNamespaceForViewModels = "ModelosDeVistas",DefaultSubNamespaceForViews = "Vistas",ViewModelSuffix = "ModeloDeVista",ViewSuffixList = new List<string>(new string[] { "Vista", "Pagina" }),NameFormat = "{1}{0}",IncludeViewSuffixInViewModelNames = false };ViewLocator.ConfigureTypeMappings(config); ViewModelLocator.ConfigureTypeMappings(config);//Resolves: //MiProyecto.ModelosDeVistas.ModeloDeVistaCliente -> MiProyecto.Vistas.VistaCliente, MiProyecto.Vistas.PaginaCliente //MiProyecto.Vistas.VistaCliente -> MiProyecto.ModelosDeVistas.ModeloDeVistaCliente //MiProyecto.Vistas.PaginaCliente -> MiProyecto.ModelosDeVistas.ModeloDeVistaClienteNew Type Mapping Methods
ViewLocator.AddDefaultTypeMapping(), ViewModelLocator.AddDefaultTypeMapping()
此方法用于添加類型映射,該映射支持給定視圖名稱后綴的標準類型和命名空間命名約定。
public static void AddDefaultTypeMapping(string viewSuffix = "View")viewSuffix參數是類型名稱的后綴。應該是“視圖”或“視圖”的同義詞。(可選)
此方法主要用于添加對具有自定義同義詞(例如“表單”、“屏幕”、“選項卡”)但使用標準命名約定的類型的支持。
雖然viewSuffix參數是可選的,默認為“View”,但沒有必要以這種方式調用此方法,因為定位器類已經為“View”和“Page”視圖名稱后綴添加了類型映射,盡管如果定位器類使用ConfigureTypeMappings()方法和修改TypeMappingConfiguration對象的ViewSuffixList屬性進行了不同的配置,則情況可能并非如此。但是,修改配置對象的ViewSuffixList屬性并重新配置locator類可以避免事后調用此方法。
請記住,如果配置對象的UseNameSuffixesInMappings屬性設置為false,則此方法不會添加任何類型映射。在這種情況下,沒有為其添加映射的默認類型命名約定。
//Add support for "Form" as a synonym of "View" using the standard type and namespace naming conventions ViewLocator.AddDefaultTypeMapping("Form"); //Resolves: MyProject.ViewModels.MainFormViewModel -> MyProject.Views.MainFormViewModelLocator.AddDefaultTypeMapping("Form"); //Resolves: MyProject.Views.MainForm -> MyProject.ViewModels.MainFormViewModelViewLocator.RegisterViewSuffix()
此方法用于向ViewLocator指示使用NameTransformer.AddRule()添加了支持自定義視圖后綴的轉換規則。調用AddNamespaceMapping()、AddTypeMapping()和AddDefaultTypeMapping()類型映射方法時,ViewLocator類會自動在內部調用此方法。
public static void RegisterViewSuffix(string viewSuffix)viewSuffix參數是類型名稱的后綴。應該是“視圖”或“視圖”的同義詞。(可選)
為了使多視圖支持正常工作,ViewLocator需要跟蹤應用程序可能使用的所有視圖后綴。盡管在使用新的類型映射方法添加名稱轉換規則時會自動管理此操作,但直接通過ViewLocator類的NameTransformer實例添加的轉換規則將繞過此注冊步驟。因此,在這種情況下需要調用ViewLocator.RegisterViewSuffix()。在添加新條目之前,該方法將對現有條目執行檢查。
//Manually add a rule to the NameTransformer to do simple text replacement independent of namespace ViewLocator.NameTransformer.AddRule("ScreenViewModel$", "Screen"); //However, we need to treat "Screen" as a synonym of "View" somehow in order to //enable multi-view support for View types with names ending in "Screen" ViewLocator.RegisterViewSuffix("Screen"); //Resolves: MyProject.ViewModels.CustomerScreenViewModel -> MyProject.Views.Customer.Master //when the context is "Master"ViewLocator.AddNamespaceMapping(),ViewModelLocator.AddNamespaceMapping()
此方法用于在源命名空間和一個或多個目標命名空間之間添加類型映射。結果類型映射創建了一個轉換規則,該規則支持標準類型命名約定,但具有自定義命名空間命名約定。或者,可以為此映射指定自定義視圖后綴。
public static void AddNamespaceMapping(string nsSource, string[] nsTargets, string viewSuffix = "View")nsSource:源類型的命名空間
nsTargets:作為數組的目標類型的名稱空間
viewSuffix:類型名稱的后綴。應該是“視圖”或“視圖”的同義詞。(可選)
public static void AddNamespaceMapping(string nsSource, string nsTarget, string viewSuffix = "View")nsSource:源類型的命名空間
nsTarget:目標類型的命名空間
viewSuffix:類型名稱的后綴。應該是“視圖”或“視圖”的同義詞。(可選)
此方法支持在nsSource參數中使用通配符(用*)。當nsSource參數使用空字符串(或string.Empty)時,作為nsTarget/nsTargets參數傳遞的命名空間將追加到源類型的命名空間。有關更多詳細信息,請參閱示例。
可以將數組作為目標命名空間的參數傳遞,以指示目標類型可以存在于多個命名空間中(“一對多”映射)。由于定位器類被設計為拾取與名稱轉換規則匹配的類型的第一個匹配項,因此,如果某個類型實際上不存在于某個目標名稱空間中,或者不同名稱空間中存在多個共享同一名稱的類型,則無所謂。此機制的一個可能用例是將ViewModel命名空間映射到自定義視圖的程序集和標準視圖的另一個程序集。如果自定義視圖的部件不存在,或者自定義視圖部件中不存在特定視圖,則ViewLocator將從標準視圖部件中拾取視圖。
//"Append target to source" mapping //Null string or string.Empty passed as source namespace is special case to allow this //Note the need to prepend target namespace with "." to make this work ViewLocator.AddNamespaceMapping("", ".Views"); //Resolves: MyProject.Customers.CustomerViewModel -> MyProject.Customers.Views.CustomerView//Standard explicit namespace mapping ViewLocator.AddNamespaceMapping("MyProject.ViewModels.Customers", "MyClient1.Views"); //Resolves: MyProject.ViewModels.CustomerViewModel -> MyClient1.Views.CustomerView//One to many explicit namespace mapping ViewLocator.AddNamespaceMapping("MyProject.ViewModels.Customers", new string[] { "MyClient1.Views", "MyProject.Views" } ); //Resolves: MyProject.ViewModels.CustomerViewModel -> {MyClient1.Views.CustomerView, MyProject.Views.CustomerView }//Wildcard mapping ViewLocator.AddNamespaceMapping("*.ViewModels.Customers.*", "MyClient1.Customers.Views"); //Resolves: MyProject.ViewModels.Customers.CustomerViewModel -> MyClient1.Customers.Views.CustomerView // MyProject.More.ViewModels.Customers.MasterViewModel -> MyClient1.Customers.Views.MasterView // MyProject.ViewModels.Customers.More.OrderHistoryViewModel -> MyClient1.Customers.Views.OrderHistoryViewViewLocator.AddSubNamespaceMapping(),ViewModelLocator.AddSubNamespaceMapping()
此方法用于通過將給定的子名稱空間替換為另一子名稱空間,在源名稱空間和一個或多個目標名稱空間之間添加類型映射。結果類型映射創建了一個轉換規則,該規則支持標準類型命名約定,但具有自定義命名空間命名約定。或者,可以為此映射指定自定義視圖后綴。
public static void AddSubNamespaceMapping(string nsSource, string[] nsTargets, string viewSuffix = "View")nsSource:源類型的子名稱空間
nsTargets:目標類型為數組的子名稱空間
viewSuffix:類型名稱的后綴。應該是“視圖”或“視圖”的同義詞。(可選)
public static void AddSubNamespaceMapping(string nsSource, string nsTarget, string viewSuffix = "View")nsSource:源類型的子名稱空間
nsTarget:目標類型的子名稱空間
viewSuffix:類型名稱的后綴。應該是“視圖”或“視圖”的同義詞。(可選)
此方法支持在nsSource參數中使用通配符(用*)。當nsSource參數使用空字符串(或string.Empty)時,作為nsTarget/nsTargets參數傳遞的命名空間將追加到源類型的命名空間。當nsSource為空字符串或以通配符開頭和結尾時,其行為與AddNamespaceMapping()的行為相同。與AddNamespaceMapping()一樣,AddSubNamespaceMapping()方法支持一對多映射。有關說明,請參閱AddNamespaceMapping()的說明。
此方法在配置時為配置對象的ViewSuffixList中的每個視圖后綴在內部調用。由DefaultSubNamespaceForViews和DefaultSubNamespaceForViewModels指定的子名稱用于映射。如果不需要“視圖”和“ViewModels”子名稱空間之間的默認映射,則可以使用適當的配置設置來消除直接調用AddSubNamespaceMapping()的需要。
//Add support for Spanish namespaces ViewLocator.AddSubNamespaceMapping("ModelosDeVistas", "Vistas"); //Resolves: MiProyecto.ModelosDeVistas.Clientes.ClienteViewModel -> MiProyecto.Vistas.Clientes.ClienteViewViewModelLocator.AddSubNamespaceMapping("Vistas", "ModelosDeVistas"); //Resolves: MiProyecto.Vistas.Clientes.ClienteView -> MiProyecto.ModelosDeVistas.Clientes.ClienteViewModel//Wildcard subnamespace mapping ViewLocator.AddSubNamespaceMapping("*.ViewModels", "ExtLib.Views"); //Resolves: MyCompany.MyApp.SomeNamespace.ViewModels.CustomerViewModel -> ExtLib.Views.CustomerViewViewLocator.AddSubNamespaceMapping("ViewModels.*", "Views"); //Resolves: MyApp.ViewModels.Some.Name.Space.CustomerViewModel -> MyApp.Views.CustomerViewViewLocator.AddSubNamespaceMapping("MyApp.*.ViewModels", "ExtLib.Views"); //Resolves: MyCompany.MyApp.SomeNamespace.ViewModels.CustomerViewModel -> MyCompany.ExtLib.Views.CustomerViewViewLocator.AddTypeMapping(),ViewModelLocator.AddTypeMapping()
此方法用于添加表示為基于正則表達式的轉換的類型映射。結果類型映射創建了一個轉換規則,該規則支持標準類型命名約定,但具有自定義命名空間命名約定。或者,可以為此映射指定自定義視圖后綴。
public static void AddTypeMapping(string nsSourceReplaceRegEx, string nsSourceFilterRegEx, string[] nsTargetsRegEx, string viewSuffix = "View")nsSourceReplaceRegEx:源命名空間的RegEx替換模式
nsSourceFilterRegEx:源命名空間的正則表達式篩選器模式
nsTargetsRegEx:目標命名空間的RegEx替換值數組
viewSuffix:類型名稱的后綴。應該是“視圖”或“視圖”的同義詞。(可選)
public static void AddTypeMapping(string nsSourceReplaceRegEx, string nsSourceFilterRegEx, string nsTargetRegEx, string viewSuffix = "View")nsSourceReplaceRegEx:源命名空間的RegEx替換模式
nsSourceFilterRegEx:源命名空間的正則表達式篩選器模式
nsTargetsRegEx:目標命名空間的RegEx替換值
viewSuffix:類型名稱的后綴。應該是“視圖”或“視圖”的同義詞。(可選)
有關創建基于正則表達式的轉換規則的詳細信息,請參閱NameTransformer上的文檔。與通過NameTransformer類添加轉換規則不同,此方法將命名空間轉換與類型名轉換分離。此外,它還支持一對多命名空間映射。有關說明,請參閱AddNamespaceMapping()的說明。
//Capture namespace fragment preceding "ViewModels." as "nsbefore" string subns = RegExHelper.NamespaceToRegEx("ViewModels."); string rxrep = RegExHelper.GetNamespaceCaptureGroup("nsbefore") + subns;//Output the namespace fragment after "Views." in the target namespace string rxtgt = @"Views.${nsbefore}"; ViewLocator.AddTypeMapping(rxrep, null, rxtgt); //Resolves: MyApp.Some.Name.Space.ViewModels.TestViewModel -> Views.MyApp.Some.Name.Space.TestView02
—
最后
原文標題:Caliburn.Micro Xaml made easy
原文鏈接:https://caliburnmicro.com/documentation/custom-conventions
翻譯:dotnet編程大全
C#技術群?:?添加小編微信mm1552923,備注:進群!
總結
以上是生活随笔為你收集整理的C# WPF MVVM开发框架Caliburn.Micro 自定义Conventions⑩的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 再见 Typora,这款 Markdow
- 下一篇: C# 是否可以将 动态或匿名类型 转成