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 :)
精彩评论