把ViewModel放在正确的地方

把ViewModel放在正确的地方

问题描述:

我有一个Silverlight项目。在App.xaml中,我们有把ViewModel放在正确的地方

<Application.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="Assets/Styles.xaml"/> 
     </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 
</Application.Resources> 

然后在Assets/Styles.xaml,我们有ViewModel。

<ResourceDictionary 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" 
xmlns:local="clr-namespace:MyWeb.MyProj" 
xmlns:sys="clr-namespace:System;assembly=mscorlib" 
xmlns:localViewModels="clr-namespace:MyWeb.MyProj.ViewModels"> 

<ResourceDictionary.MergedDictionaries> 

</ResourceDictionary.MergedDictionaries> 

<localViewModels:MyProjViewModel x:Key="ViewModel" /> 
... 
<telerikGridView:RadGridView 
    ... 
    ItemsSource="{Binding Schedules}" 
    SelectedItem="{Binding SelectedWeek, Mode=TwoWay, Source={StaticResource ViewModel}}"> 

最后在MainPage.xaml.cs中,我们有

private MyProjViewModel viewModel; 

public MyProjViewModel ViewModel 
{ 
    get 
    { 
     if (this.viewModel == null) 
     { 
      this.viewModel = new MyProjViewModel(); 
     } 
     return this.viewModel; 
    } 
    set 
    { 
     if (this.viewModel != value) 
     { 
      this.viewModel = value; 
     } 
    } 
} 

然后在构造函数中,我们使用视图模型作为

public MainPage() 
{ 
    InitializeComponent(); 
    this.DataContext = this.ViewModel; 
    this.ViewModel = this.DataContext as MyProj; 

虽然它的工作原理,但我不知道如果它是使用ViewModel的最佳结构,因为它放置在Styles.xaml中。如果没有,如何纠正?

+1

我会从样式中删除ViewModel定义。把它放在MainPage构造函数中。 –

如果您希望ViewModel的一个特定实例可用于整个应用程序的生命周期,您可以像Resource一样在Resource Dictionary中定义它(当然,您必须从资源字典中引用它而不是像你在你的问题中那样使用)。

更好的解决方案是在视图的构造函数中创建它(没有styles.xaml中的定义)。

public MyProjectViewModel ViewModel { get; set; } 

public MainPage() 
{ 
    InitializeComponent(); 
    this.ViewModel = new MyProjViewModel(); 
    this.DataContext = this.ViewModel; 
}