我试图使应用程序使用MVVM。这篇文章的最大部分是关于我尝试过什么以及我已经实现了什么的解释。问题在文章底部。使用的Localizer
类只是此处的一个示例,可以轻松替换为另一个类。
我有一个类库
,其中包含一个名为Localizer
的类。该类的目的是可以在应用程序运行时更改应用程序的语言,而无需重新启动应用程序。`Localizer必须实例化才能使用,但一旦实例化,就可以在整个应用程序中使用。(该类使用应用程序资源本地化应用程序。)
我想到的第一种方法是将Localizer
作为public static class
,并具有public static void Initialize
方法。这样,我可以像这样初始化Localizer
Localizer.Initialize(/* Needed arguments here */);
在应用程序级别使用它,并将其用于我的类库或应用程序中,就像这样
string example = Localizer.GetString(/* A key in the resource dictionary */);
考虑到类库是由我编写(只有我拥有源代码),而其他人使用这个类库却不了解源代码(他们只知道该类库能做什么),因此我需要在某种“如何使用这个类库”的说明中明确声明,在应用程序级别上调用
Localizer.Initialize
以便在他们的整个应用程序中都可以使用它。经过一些研究,很多人表示这是一种不好的做法,并建议研究依赖注入(DI)和控制反转(IoC),所以我也这样做了。我了解到DI基本上与我的第一种方法相同,但是去除了静态内容,将
Localizer.Initialize
用作构造函数并将实例化的类注入到我的其他类中。所以第二种方法是依赖注入,这就是我卡住的地方。我设法让我的应用程序仅使用一个
MainWindowView
和MainWindowViewModel
来编译代码:protected override void OnStartup(StartupEventArgs e)
{
ILocalizer localizer = new Localizer(Current.Resources, System.Reflection.Assembly.GetExecutingAssembly().GetName().Name, "Languages", "Language", "en");
var mainWindowViewModel = new MainWindowViewModel(localizer);
var mainWindowView = new MainWindowView { DataContext = mainWindowViewModel };
mainWindowView.Show();
base.OnStartup(e);
}
上面的代码是将
localizer
注入到MainWindowViewModel
中。这样就不需要向MainWindowView
添加额外的代码,而且视图与视图模型绑定。在
MainWindowViewModel
中,构造函数如下(注意,消息框被调用到了其他地方,但在此处移动以最小化代码):ILocalizer _localizer;
public MainWindowViewModel( ILocalizer localizer)
{
_localizer = localizer;
MessageBox.Show(_localizer.GetString(/* A key in the resource dictionary */));
}
上面的代码仍然可以编译并正常运行,没有出现异常。当我在我的类库中有一个需要localizer实例的视图和视图模型时,问题就会发生。
我认为当我在我的应用程序集中有一个UserControl时,我有一个解决方案,但感觉比使用静态类更加复杂。通常,我将一个UserControl的视图模型绑定到它的代码后面的视图上。这样,我就可以像这样简单地将UserControl添加到我的.xaml代码中,例如,而不需要额外的麻烦。这样,视图模型的父视图模型就不必考虑子视图模型。
使用DI,我会在我的父级中这样做(子级与上一个代码块中的相同):
视图
<n:UserControl1 DataContext="{Binding UC1ViewModel}" />
视图模型
public UserControl1ViewModel UC1ViewModel { get; set; }
ILocalizer _localizer;
public MainWindowViewModel(ILocalizer localizer)
{
_localizer = localizer;
UC1ViewModel = new UserControl1ViewModel(localizer);
}
目前还没有出现任何问题,一切都运行良好。唯一变化的是DataContext
在父视图中设置,而DataContext
的内容在父视图的视图模型中设置。
问题
我在我的class library
中还有几个UserControls
。这些可以被class library
的用户使用,但不能更改它们。其中大部分UserControls
是一些固定的pages
,用于显示关于人、汽车等信息的信息。意图是例如,人名标签在英语中为“Name”,在荷兰语中为“Naam”等(所有标签都在视图中声明并且正常工作),但是代码背后也有文本需要本地化,这就是我卡住的地方。
我应该像在我的应用程序程序集中处理UserControl
一样处理此问题吗?如果在单个父视图中使用20多个这样的UserControls
,这会感觉非常低效。
我还觉得我没有完全正确地实现DI。