无法在 WPF 中使用 MVVM 在设计时进行数据绑定 - ViewModel 属性永远不会被调用

发布于 2024-08-22 14:12:14 字数 2120 浏览 1 评论 0原文

好吧,我正在为此烦恼,所以任何帮助将不胜感激!

我正在使用 MVVM 模式构建 WPF 应用程序。

为了在设计时获取数据,我将 Ninject 依赖注入框架与服务定位器结合使用(非常类似于 http://jonas.follesoe.no/YouCardRevisitedImplementingDependencyInjectionInSilverlight.aspx

(因为我使用的是 WPF 而不是 Silverlight,所以我检查设计时属性的方式略有不同,但我相信它是适用)

我无法让它在设计时工作,无论我做什么,它在运行时似乎都无法正常工作。

这是我的 Ninject 模块的代码:

public class ViewModelModule : StandardModule
{
    public override void Load()
    {
        bool isRuntime = !ViewModelBase.IsInDesignMode;

        if (isRuntime)
        {
            Bind<IViewModel>().To<MyViewModel>();                
        }
        else
        {
            Bind<IViewModel>().To<MyDesignTimeViewModel>();
        }
    }
}

MyDesignTimeViewModel< /code> 是一个普通的 CLR 对象,它返回硬编码数据来代替 MyViewModel 上的所有相同属性。

服务定位器如下所示:

 public class ViewModelLocator
 {
    private static IKernel kernel;

    static ViewModelLocator()
    {
        if (kernel == null)
        {
            kernel = new StandardKernel(new ViewModelModule());
        }
    }      

    public IViewModel ViewModel
    {
        get
        {
            var vm = kernel.Get<IViewModel>();
            return vm;
        }
    }
}

并且 XAML 按如下方式绑定页面的 DataContext(尽管我)。已经尝试了几种不同的声明方法,所有方法都具有相同的结果):(

<Page.DataContext>
    <Binding Source="{StaticResource viewModelLocator}" Path="ViewModel" />        
</Page.DataContext>

其中 viewModelLocator 在合并到该文件顶部的 ResourceDictionary 中声明)。

正如我所说,这在运行时工作得很好,即使我在运行时将 Ninject 绑定切换为使用 MyDesignTimeViewModel,它也会成功显示虚拟数据。我的一个绑定中有一个虚拟转换器,用于查看通过的内容,并且它在运行时调用,而不是在设计时调用(我一整天都在使用单独的 Visual Studio 进程疯狂地调试设计时实例,因为根据 MSDN 建议!)

在设计时,Ninject 绑定将与内核实例化一起继续进行。然后 viewModel 被调用,它返回一个 DesignTimeViewModel 以及我所有的硬编码数据。但与视图模型上任何属性的实际绑定似乎永远不会被调用(虚拟转换器断点永远不会被命中)。

我真的看不出我做错了什么。任何方向的指示都将不胜感激,因为在这个阶段我只是感到困惑。谢谢 :)

Ok, I'm pulling my hair out over this, so any help will be hugely appreciated!

I'm building a WPF application using the MVVM pattern.

In an attempt to get data in at design time I am using the Ninject dependency injection framework in conjunction with a service locator (much like the example in an article at http://jonas.follesoe.no/YouCardRevisitedImplementingDependencyInjectionInSilverlight.aspx

(as I'm using WPF and not Silverlight I check for design time properties slightly differently but otherwise I believe it is applicable).

I can't get it to work at design time, no matter what I do the binding doesn't seem to even get called. It works fine at runtime.

Here's the code for my Ninject module:

public class ViewModelModule : StandardModule
{
    public override void Load()
    {
        bool isRuntime = !ViewModelBase.IsInDesignMode;

        if (isRuntime)
        {
            Bind<IViewModel>().To<MyViewModel>();                
        }
        else
        {
            Bind<IViewModel>().To<MyDesignTimeViewModel>();
        }
    }
}

MyDesignTimeViewModel is a plain CLR object that returns hardcoded data in place of all the same properties on MyViewModel.

The Service Locator is as follows:

 public class ViewModelLocator
 {
    private static IKernel kernel;

    static ViewModelLocator()
    {
        if (kernel == null)
        {
            kernel = new StandardKernel(new ViewModelModule());
        }
    }      

    public IViewModel ViewModel
    {
        get
        {
            var vm = kernel.Get<IViewModel>();
            return vm;
        }
    }
}

And the XAML binds the DataContext of the page as follows (though I've tried a few different ways of declaring it, all with the same result):

<Page.DataContext>
    <Binding Source="{StaticResource viewModelLocator}" Path="ViewModel" />        
</Page.DataContext>

(where the viewModelLocator is declared in a ResourceDictionary that is merged at the top of this file).

As I said this works fine at runtime, even if I switch my Ninject binding to use MyDesignTimeViewModel at runtime it successfully displays the dummy data. I've got a dummy converter in one of my bindings to see what gets passed through and this gets called at runtime but not at design time (I've been frantically debugging a design time instance using a seperate Visual Studio process all day, as per the MSDN recommendations!)

At design time the Ninject binding goes ahead, along with the kernel instantiation. Then the viewModel gets called for and it returns a DesignTimeViewModel, along with all my hardcoded data. But the actual binding to any of the properties on the viewmodel never seem to get called (the dummy converter breakpoint never gets hit).

I really can't see what I'm doing wrong. Any pointers in any direction would be greatly appreciated as at this stage I'm just baffled. Thanks :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

烟火散人牵绊 2024-08-29 14:12:14

这里有一些可以尝试的事情:

  1. 在调试设计器时,检查是否有任何警告/错误。
  2. 尝试使用最新版本的 Snoop 来窥探您的设计器,它允许您附加到 Visual Studio。
  3. 尝试调试绑定。也许会出现一些有趣的事情。

并且不要忘记检查 DataContexts :)。

希望至少有一些帮助。

干杯

Here are couple things to try:

  1. While you are debugging designer, check whether you have any warnings/errors.
  2. Try to snoop your designer with latest version of Snoop, which allows you to attach to the Visual Studio.
  3. Try to debug bindings. Maybe something interesting comes out.

And don't forget to check DataContexts :).

Hope at least something would help.

Cheers

羁拥 2024-08-29 14:12:14

也许 Visual Studio 2010 和 Expression Blend 4 的新设计时功能是您的一个选择。

其工作原理如 WPF 应用程序框架 (WAF)。请下载.NET4版本。

Maybe the new design-time features of Visual Studio 2010 and Expression Blend 4 are an option for you.

How it works is shown in the BookLibrary sample application of the WPF Application Framework (WAF). Please download the .NET4 version.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文