1

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

然而,我“感觉”我做的不对。我相信我只需要一个 ViewModel 实例。但是因为main.xaml.cs和menu.xaml.cs互不认识,所以不知道怎么共享实例。

4

3 回答 3

1

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

第一种方法:作为 XAML 资源

您的型号:

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

应用程序.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}}"/>
于 2013-10-27T14:35:44.620 回答
0

您可以有另一个包含您的MenuViewand的视图,并在包装​​视图上MainView设置,然后您的and将继承并使用相同的.DataContextMenuViewMainViewDataContext

包装器视图的示例 XAML:

<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>

WrapperView 的代码隐藏:

public partial class YourView : UserControl
{
    public YourView()
    {
        InitializeComponent();
        DataContext = new YourViewModel();
    }
}
于 2013-10-27T07:12:48.137 回答
0

您可以将两个用户控件放入MainWindow.Xaml并设置数据上下文MainWindow.xaml.cs或在视图模型类型的视图模型中公开静态属性,如下所示:

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

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

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

DataContext = ViewModel.Instance;

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

于 2013-10-27T07:54:28.717 回答