zoukankan      html  css  js  c++  java
  • WPF程序只允许一个启动在MVVMLight框架下找不到资源的问题

      需求要求只有一个程序启动,OK,这个很简单,以前在Form中我们很简单就可以实现,我们考虑的就是用Mutex类来向线程授予共享资源独占访问权。但是如果使用的是WPF,还使用了MVVMLight,恭喜你,你马上要面临一个很诡异的错误,我们看下面:

       我们使用net3.5,新建一个MVVMLight模板的WPF程序。如图示:

                                                        _XOKVYP49K9$Y~ZH5RM%~6N

      MVVM自动帮我们添加了ViewModel、Model文件夹。其中MainViewModel是MainWindow的ViewModel,ViewModelLocator是进行ViewModel和View定位文件,即指定哪个View使用哪个ViewModel。我在一般项目中一般不使用该文件,有时候很简单设置DataContex就可以绑定使用ViewModelLocator反而更麻烦。而我们今天所说的错误就来自这个ViewModelLocator。

        我们先来解决单一程序启动的问题。按照以往的惯例,我们在App.xaml.cs中重写OnStartup来增加启动逻辑。看代码:

        我们知道,App.xaml中已设置StartupUri="MainWindow.xaml",我们再定义时会重复,删掉StartupUri="MainWindow.xaml"后,OK,单一程序启动的逻辑我们应该没有写错,现在我们debug试一下。

     1  public partial class App : Application
    2 {
    3 static App()
    4 {
    5 DispatcherHelper.Initialize();
    6
    7 }
    8
    9 protected override void OnStartup(StartupEventArgs e)
    10 {
    11 base.OnStartup(e);
    12 bool startupFlag;
    13 Mutex mutex = new Mutex(true,"BoeLottery",out startupFlag);
    14 if(!startupFlag)
    15 {
    16 MessageBox.Show("程序已经启动!");
    17 Environment.Exit(0);
    18
    19 }
    20 else
    21 {
    22 MainWindow mainWindow = new MainWindow();
    23 mainWindow.Show();
    24 mainWindow.DataContext = new MainViewModel();
    25 }
    26
    27 }
    28
    29 }


    ~I43LDL[NU_R329C)S1OYBW

    奇怪,这时候,{Locator}资源找不到了,Locator是MVVMLight自动生成的ViewModelLocator的引用名称。在App.xaml有Locator的定义。

    <Application.Resources> <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" /> </Application.Resources>

    那么,好好的Locator怎么找不到了呢?我们回想一下做过了哪些操作,注释掉重写OnStartup方法后问题依旧,取消注释。对,我们还删除了StartupUri="MainWindow.xaml"这一句代码,添加回去试试,debug此时成功了,但是因为有StatupUri,这时候我们重写的内容是没有意义的。

    为什么删除StartupUri会引起这样的错误呢?

    我们知道StaticResource对该资源的查找行为类似于加载时查找,它会查找以前从当前 XAML 页的标记中加载的资源以及其他应用程序源,并且将该资源值生成为运行时对象中的属性值。App.cs文件中的MainWindow是重写时动态生成的,而StaticResource在这之前已经进行了数据绑定,所以抛出了Data.Binding的异常,更深层次的解释要问微软了。解决办法如下:

    我们注释掉MainWindow中的DataContext="{Binding Main, Source={StaticResource Locator}}",在App.xaml.cs中

                    mainWindow.Show();                    一句后面添加

                    mainWindow.DataContext = new MainViewModel();

    此时mainWindow动态生成时指定DataContext。

    Debug成功。问题clear。


     

    分享到: 更多
  • 相关阅读:
    commit(), commitNow()和commitAllowingStateLoss()
    Android 7.0 Nougat牛轧糖 发布啦
    Android Weekly Notes Issue #219
    Android Weekly Notes Issue #218
    CoordinatorLayout, AppBarLayout, CollapsingToolbarLayout使用
    Using Dagger2 in Android
    冰雪奇缘,白色世界:四个IT人的四姑娘山双桥沟游记
    你必须知道的容器日志 (2) 开源日志管理方案 ELK/EFK
    你必须知道的容器日志 (1) Docker logs & logging driver
    2019 .NET China Conf:路一直都在,社区会更好
  • 原文地址:https://www.cnblogs.com/haisa/p/2294535.html
Copyright © 2011-2022 走看看