2个XAML使用相同的ViewModel类,但有2个单独的实例

时间:2013-10-27 03:55:35

标签: c# wpf xaml mvvm

我有一个很长的xaml。然后我为xaml的菜单部分创建了一个UserControl以使其干净(我认为)。在我的主要xaml代码隐藏中,我实例化了我的ViewModel类并将其设置为主xaml的DataContext。为了让main和menu xaml相互通信,我选择使用相同的视图模型作为菜单代码隐藏的数据上下文。我实例化了另一个ViewModel类。到目前为止,我的代码工作正常。

然而,我觉得'我做得不对。我相信我只需要一个ViewModel实例的实例。但由于main.xaml.cs和menu.xaml.cs彼此不了解,我不知道如何共享实例。

3 个答案:

答案 0 :(得分:1)

您可以向App.xaml.cs添加属性,然后在控件中绑定它。

第一种方法:作为XAML资源

你的模特:

public class MyViewModel
{
    public int Hello { get; set; }    
}

App.xaml.cs:

<Application x:Class="WpfApplication12.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:wpfApplication12="clr-namespace:WpfApplication12"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <wpfApplication12:MyViewModel x:Key="MyViewModel" />
    </Application.Resources>
</Application>

小注意:不需要使用x:Shared="True"注释对象,因为它是默认值,将返回相同的实例。 http://msdn.microsoft.com/en-us/library/aa970778.aspx

您的用户控件:

<UserControl x:Class="WpfApplication12.UserControl2"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d"
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid DataContext="{Binding Mode=OneWay, Source={StaticResource MyViewModel}}">
        <TextBlock Text="{Binding Path=Hello}" />
    </Grid>
</UserControl>

现在,由于您的模型是资源,您可以通过创建属性来检索它:

public MyViewModel MyViewModel
{
    get { return Application.Current.FindResource("MyViewModel") as MyViewModel; }
}

(您可能希望将该引用存储在字段中。)

第二种方法:作为传统财产

如果由于某些原因您更喜欢传统属性,请使用以下语法:

注意,该属性是静态的,并在静态构造函数中初始化。

public partial class App : Application
{
    static App()
    {
        MyViewModel = new MyViewModel();
    }

    public static MyViewModel MyViewModel { get; set; }
}

在用户控件中绑定到它:

<Grid DataContext="{Binding Source={x:Static wpfApplication12:App.MyViewModel}}"/>

答案 1 :(得分:0)

您可以拥有另一个视图,其中包含MenuViewMainView,并在包装​​器视图上设置DataContext,然后同时设置MenuView和{{1}将继承并使用相同的MainView

Wrapper View的XAML示例:

DataContext

和WrapperView的Codebehind:

<UserControl x:Class="WpfApplication1.YourView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:wpfApplication1="clr-namespace:WpfApplication1"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <wpfApplication1:YourMenuView Grid.Row="0"/>
        <wpfApplication1:YourMainView Grid.Row="1"/>
    </Grid>
</UserControl>

答案 2 :(得分:0)

您可以将两个usercontrol放入MainWindow.Xaml并在MainWindow.xaml.cs中设置数据上下文,或在viewmodeltype的viewmodel中公开静态属性,如下所示:

public class ViewModel
{
   private static ViewModel instance = new ViewModel();

   public static Viewmodel Instance
   {
       get
       {
          return instance;
       }
   }
} 

在xaml.cs中,您可以执行以下操作:

DataContext = ViewModel.Instance;

您可以在任意数量的xaml.cs中重复此行,对于所有XAML,现在您只有一个实例。