Can't databind at design time in WPF using MVV

2019-06-24 05:02发布

问题:

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

回答1:

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



回答2:

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.