尝试:避免将静态实例作为datacontext

时间:2014-05-12 19:52:37

标签: c# wpf mvvm datacontext

我在将Windows视图模型共享到Windows托管框架时遇到问题。

因此我为主窗口创建了一个静态视图模型,因此任何类都可以编辑它的属性:

class GUICollection
{
    public static MainWindowViewModel MainWindowViewModel = new MainWindowViewModel();

}

然后将其设置为MainWindows datacontext:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = GUICollection.MainWindowViewModel;
    }
}

这是windows xaml:

<Window x:Class="MVVMFrameQuestiontoStackOverflow.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Frame NavigationUIVisibility="Hidden" Source="{Binding MainWindow.FrameURI}"/>
</Grid>

是视图模型:

class MainWindowViewModel
{
    private string startUpURI;
    private object startUpDataContext;
    private MainWindowModel mainWindow;


    public MainWindowViewModel()
    {
        startUpURI = "pack://application:,,,/MVVMFrameQuestiontoStackOverflow;component/Page1.xaml";
        mainWindow = new MainWindowModel(startUpURI);
    }

    /// <summary>
    /// Gets the MainWindow instance
    /// </summary>
    public MainWindowModel MainWindow
    {
        get
        {
            return mainWindow;
        }
    }
}

所以从这里我可以选择框架Source,这意味着我可以选择要显示的视图。但是我想知道我是否可以避免静态初始化并仍然能够访问主窗口FrameURI属性(这是我当前的逻辑):

    public Page1()
    {
        InitializeComponent();
        DataContext = new MainMenuViewModel();
        //Statement below causes an exception, but the whole issue is about accesing this without using a static instance.
        GUICollection.MainWindowViewModel.MainWindow.FrameURI = "Change MainWindows FrameURI property!";
    }

是否可以在不使用静态类的情况下生成相同的行为?如果是这样,一个例子将受到热烈的赞赏。

先谢谢!

1 个答案:

答案 0 :(得分:1)

我认为你的问题实际上是你无法理解MVVM并使用MVC和MVVM之间的混合:你在ViewModel中创建视图(mainWindows)是禁止的。

您的应用必须加载主视图。

在主视图的构造函数中,您应该将视图模型创建为私有字段。

当您创建新窗口时(并且您应该只从视图中执行此操作,而不是从视图模型中执行此操作),您将提供viewmodel datacontext对象作为新视图的参数,它将赋予它自己的viewmodel通过参数。

如果您在所有应用程序中共享了Model对象,请在App启动方法中创建它,并通过它们的构造函数将其作为参数传递给它。