概要:

将所有的VM在加载到Application的Static Resource中,然后在View中用标签指定。

实现:

1)采用特性指定要添加到StaticResource中的对象





​public​​​​class​​​​StaticResourceAttribute : Attribute ​

​{ ​

​public​​​​string​​​​Key { ​​​​get​​​​; ​​​​set​​​​; } ​

 

​public​​​​StaticResourceAttribute(​​​​string​​​​key) ​

​{ ​

​this​​​​.Key = key; ​

​} ​

​}​

2)从当前的程序集中,把所有标记了StaticResourceAttribute的VM加载到AppResource中





​view source​​​​print​​​​?​


​public​​​​class​​​​ViewModelManager ​

​{ ​

​private​​​​static​​​​Application app = Application.Current; ​

 

​public​​​​static​​​​void​​​​InjectViewModelsToResources() ​

​{ ​

​Assembly executingAssembly = Assembly.GetCallingAssembly(); ​

​foreach​​​​(Type type ​​​​in​​​​executingAssembly.GetTypes()) ​

​{ ​

​var attributes = type.GetCustomAttributes(​​​​false​​​​); ​

 

​foreach​​​​(var attribute ​​​​in​​​​attributes) ​

​{ ​

​if​​​​(attribute ​​​​is​​​​StaticResourceAttribute) ​

​{ ​

​var obj = Activator.CreateInstance(type); ​

​if​​​​(!app.Resources.Contains(type.Name)) ​

​app.Resources.Add(type.Name, obj); ​

​} ​

​} ​

​} ​

​} ​

 

​public​​​​static​​​​T GetViewModelFromResources<T>() ​

​{ ​

​var key = ​​​​typeof​​​​(T).Name; ​

​if​​​​(app.Resources.Contains(key)) ​

​return​​​​(T)app.Resources[key]; ​

​else​

​return​​​​default​​​​(T); ​

​} ​

​}​

在主窗体中调用:





​view source​​​​print​​​​?​


​public​​​​partial​​​​class​​​​MainPage : UserControl ​

​{ ​

​public​​​​MainPage() ​

​{ ​

​ViewModelManager.InjectViewModelsToResources(); ​

 

​InitializeComponent();          ​

​} ​

​}​

3)View写法





​view source​​​​print​​​​?​


​<​​​​UserControl​​​​x:Class​​​​=​​​​"XXX .LoginView"​​​​〉 ​

​<UserControl.DataContext> ​

​<​​​​Binding​​​​Source​​​​=​​​​"{StaticResource LoginViewModel}"​​​​/> ​

​</​​​​UserControl.DataContext​​​​> ​

 

 

​</​​​​UserControl​​​​>​

结论:

这样处理后,实现了VM的"单例",多个View关联同一个VM时可以共享数据。


概要:

将所有的VM在加载到Application的Static Resource中,然后在View中用标签指定。

实现:

1)采用特性指定要添加到StaticResource中的对象





​view source​​​​print​​​​?​


​public​​​​class​​​​StaticResourceAttribute : Attribute ​

​{ ​

​public​​​​string​​​​Key { ​​​​get​​​​; ​​​​set​​​​; } ​

 

​public​​​​StaticResourceAttribute(​​​​string​​​​key) ​

​{ ​

​this​​​​.Key = key; ​

​} ​

​}​

2)从当前的程序集中,把所有标记了StaticResourceAttribute的VM加载到AppResource中





​public​​​​class​​​​ViewModelManager ​

​{ ​

​private​​​​static​​​​Application app = Application.Current; ​

 

​public​​​​static​​​​void​​​​InjectViewModelsToResources() ​

​{ ​

​Assembly executingAssembly = Assembly.GetCallingAssembly(); ​

​foreach​​​​(Type type ​​​​in​​​​executingAssembly.GetTypes()) ​

​{ ​

​var attributes = type.GetCustomAttributes(​​​​false​​​​); ​

 

​foreach​​​​(var attribute ​​​​in​​​​attributes) ​

​{ ​

​if​​​​(attribute ​​​​is​​​​StaticResourceAttribute) ​

​{ ​

​var obj = Activator.CreateInstance(type); ​

​if​​​​(!app.Resources.Contains(type.Name)) ​

​app.Resources.Add(type.Name, obj); ​

​} ​

​} ​

​} ​

​} ​

 

​public​​​​static​​​​T GetViewModelFromResources<T>() ​

​{ ​

​var key = ​​​​typeof​​​​(T).Name; ​

​if​​​​(app.Resources.Contains(key)) ​

​return​​​​(T)app.Resources[key]; ​

​else​

​return​​​​default​​​​(T); ​

​} ​

​}​

在主窗体中调用:





​public​​​​partial​​​​class​​​​MainPage : UserControl ​

​{ ​

​public​​​​MainPage() ​

​{ ​

​ViewModelManager.InjectViewModelsToResources(); ​

 

​InitializeComponent();          ​

​} ​

​}​

3)View写法





​<​​​​UserControl​​​​x:Class​​​​=​​​​"XXX .LoginView"​​​​〉 ​

​<UserControl.DataContext> ​

​<​​​​Binding​​​​Source​​​​=​​​​"{StaticResource LoginViewModel}"​​​​/> ​

​</​​​​UserControl.DataContext​​​​> ​

 

 

​</​​​​UserControl​​​​>​

结论:

这样处理后,实现了VM的"单例",多个View关联同一个VM时可以共享数据。