遵循多个指南,我使用wpf .net 4.7.1和mvvm-light具有类似的应用程序布局。我是WPF BTW的新手。
app.xaml:
<Application x:Class="My.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:viewmodel="clr-namespace:My.ViewModel"
StartupUri="ViewMainView.xaml">
<Application.Resources>
<ResourceDictionary>
<viewmodel:ViewModelLocator x:Key="Locator" />
</ResourceDictionary>
</Application.Resources>
将" ViewModeLocator"类注册为资源,并将WPF启动设置为" view/mainview.xaml"。
mainview.xaml:
<Window x:Class="My.View.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Window.DataContext>
<Binding Path="Main" Source="{StaticResource Locator}"/>
</Window.DataContext>
在使用视图定位器模式的情况下使用了ViewModeLocator。在此,将DataContext设置为" MainViewModel"(未显示(。尽管我不喜欢这样,但我可以在WPF XAML上下文中忍受它。但是,现在事实证明,我需要在视图的代码方面具有依赖性(而不是ViewModel(。
mainview.cs:
public partial class MainView : INotifyPropertyChanged
{
public MainView()
{
// Need to access dependency here.
}
}
现在,我可以直接在该构造函数中调用ViewMododelocator,并从我的IOC容器中解析,但是我完全介入并接受了该模式。
我宁愿将依赖项注入ctor中,如果可能的话,我还将完全放置ViewModeLocator,并在此处注入ViewModel。
所以问题是,是否有一些标准的指导WPF应用程序使用我的容器?如果是的话,走这条路并不使用ViewModeLocator的东西是否可以?
您绝对不必使用 ViewModelLocator
(旁注,服务定位器模式最近作为反pattern的批评,但我会让你组成你的自己的意见(。MVVM Light和其他库基本上使您可以使用工具套件。您不需要使用所有工具,也只能使用特定域所需的内容。
在ViewModelLocator
之外,有两种称为ViewModel First
和View First
的模式都有其Pro和Cons。但是,这两者都提供了将代码解除的方法,这意味着以后再切换并不难。
对于使用MVVM Light构建应用程序的应用程序而没有服务定位器,我对视图的实现First方法看起来像这样。
我听说过ViewModel First
是首选的观点,但是我首先发现视图对测试驱动开发(TDD(
app.xaml.cs(后面的应用程序代码(
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var bootStrapper = new BootStrapper();
//Container Builder
var container = bootStrapper.BootStrap();
var mainWindow = container.Resolve<MainWindow>();
mainWindow.Show();
}
}
bootstrapper.cs(在这种情况下,我正在使用autoFac,但您可以轻松替代。(
public class BootStrapper
{
public IContainer BootStrap()
{
var builder = new ContainerBuilder();
builder.RegisterType<MainWindow>().AsSelf();
builder.RegisterType<MainWindowViewModel>().AsSelf();
return builder.Build();
}
}
mainWindowViewModel.cs
//I rolled my own ViewModelBase, but you can use MVVM Light's ViewModelBase
public class MainWindowViewModel : ViewModelBase
{
public string DisplayProgram
{
get { return _displayProgram; }
//MVVM Light's ViewModelBase uses RaisePropertyChanged();
set { _displayProgram = value; OnPropertyChanged(); }
}
public void Initialize()
{
//Called from view code behind.
}
}
mainwindow.xaml.cs(背后的mainwindow代码(
//When MainWindow.Show()..
public partial class MainWindow : Window
{
private readonly MainWindowViewModel _viewModel;
//Container resolves dependencies
public MainWindow(MainWindowViewModel viewModel)
{
//Let base Window class do its thing.
InitializeComponent();
//Handle loaded event
Loaded += MainWindowLoaded;
//Hold on to the MainWindowViewModel, and set it as the windows DataContext
_viewModel = viewModel;
DataContext = _viewModel;
}
private void MainWindowLoaded(object sender, RoutedEventArgs e)
{
_viewModel.Initialize();
}
}