开发者

How to get a “null” from ObjectDataProvider in design mode?

I put the instance of one of the VMs in a resource dictionary like:

<ObjectDataProvider ObjectType="{x:Type WpfApplication1:MyViewModel}" x:Key="TheViewModel"/>

I bind the DataContext of some user controls to this:

<WpfApplication1:UserControl1 x:Name="UsrCtrl1" DataContext="{StaticResource TheViewModel}"/>

and it works fine at the runtime, because all connections and servers are available and a lot of logical objects are correctly initialized.

The problem is, in the design time I get a lot of exceptions (there are many such VMs), that make the work with very difficult.

Is it possible somehow to say in XAML if Compo开发者_JAVA百科nentModel:DesignerProperties.IsInDesignMode (xmlns:ComponentModel="clr-namespace:System.ComponentModel;assembly=PresentationFramework") is true then x:null, otherwise create my VM WpfApplication1:MyViewModel ??? I tried a lot, but was unable to get the right solution, but I cannot believe this is not possible. For any idea (maybe a tested example) thanks in advance.


The way I've dealt with this in the past involves providing an interface for your viewmodels and having the views ask for their viewmodel from a viewmodel locator class. For example, you'd have the following viewmodels:

public interface IMainViewModel
{
    double Foo { get; }
    double Bar { get; }
}

public class RealMainViewModel : IMainViewModel
{
    // implementation of IMainViewModel, this one does your data access
    // and is used at run time
}

public class FakeMainViewModel : IMainViewModel
{
    // implementation of IMainViewModel, this one is fake
    // and is used at design time
}

The viewmodel locator would look like the following:

public class ViewModelLocator
{
    public static IMainViewModel MainViewModel
    {
        get
        {
            if (Designer.IsDesignMode)
            {
                return new FakeMainViewModel();
            }
            else
            {
                return new RealMainViewModel();
            }
        }
    }
}

Finally, you'll include a reference to ViewModelLocator in App.xaml:

<Application.Resources>
    <ResourceDictionary>
        <yourNamespace:ViewModelLocator x:Key="ViewModelLocator" />
    </ResourceDictionary>
</Application.Resources>

This way, you can bind to the viewmodel property in ViewModelLocator and have your code do the work for injecting the real and fake viewmodel when appropriate:

<WpfApplication1:UserControl1 x:Name="UsrCtrl1" DataContext="{Binding Path=MainViewModel, Source={StaticResource ViewModelLocator}}"/>

I also found an article that provides another example. Note that I wrote this code on-the-fly in Notepad so I apologize if there are any typos.


I believe you can use the following in your UserControl1 tag to define a Design-Time DataContext

xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
mc:Ignorable="d" 
d:DataContext="{x:Null}"

I haven't actually tested it since I usually don't use the designer window, but in theory it should work :)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜