如何使用d:DesignInstance与没有默认构造函数的类型?

时间:2011-12-12 09:28:57

标签: .net xaml data-binding

我正在将文本框绑定到对象,如下所示:

  <TextBlock d:DataContext="{d:DesignInstance ViewModel:TaskVM }" 
             Text="{Binding Title}" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown">
  </TextBlock>

现在我想知道如何在设计过程中显示模拟数据。我尝试过这样的事情:

  <TextBlock Text="{Binding Path=Title}" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown">
    <d:DesignProperties.DataContext>
       <ViewModel:TaskVM Title="Mock"/>
    </d:DesignProperties.DataContext>
  </TextBlock>

但是,由于TaskVM没有默认的ctor,我找到了“No default constructor”。

我知道当我使用d:DataContext="{d:DesignInstance ViewModel:TaskVM }"时,它会创建一个模拟数据类型。有没有办法让我设置这个模拟类型的属性?

谢谢!

3 个答案:

答案 0 :(得分:42)

要在XAML中实例化类型,需要使用默认构造函数。作为一种解决方法,您只需创建一个TaskVM的子类,它将具有默认的构造函数,并将其用作设计时数据上下文。

<TextBlock d:DataContext="{d:DesignInstance ViewModel:DesignTimeTaskVM }" 
           Text="{Binding Title}" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown">
</TextBlock>

另一种方法是将d:IsDesignTimeCreatable设置为False,并在运行时为您创建替换类型(使用TaskVM类型作为“形状”)。

<TextBlock d:DataContext="{d:DesignInstance ViewModel:DesignTimeTaskVM, IsDesignTimeCreatable=False}" 
           Text="{Binding Title}" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown">
</TextBlock>

答案 1 :(得分:5)

您可以向VM添加默认构造函数。然后,它可以检查它是否处于设计时间并为其属性设置适当的设计时值。

答案 2 :(得分:4)

另一种方法是使用静态类来保存视图模型并从XAML调用该类。 这是一个例子:

xaml使用视图模型工厂来创建设计数据上下文:

xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DataContext="{x:Static local:ViewModelFactory.ViewModel}"


静态ViewModelFactory在其构造函数中构造视图模型,并将其存储在公共属性中,可以从外部(从XAML)访问它:

public static class ViewModelFactory
{
    /// <summary>
    /// Static constructor.
    /// </summary>
    static ViewModelFactory()
    {
        ViewModel = new TypeOfViewModel(null);

        // further configuration of ViewModel
    }

    public static TypeOfViewModel ViewModel
    {
        get; set;
    }
}



请注意TypeOfViewModel类没有无参数构造函数。 因此ViewModelFactory必须传递一些值,在本例中为null

因此,在这种情况下,TypeOfViewModel类需要以一种方式实现,即它知道在设计时间内传入的依赖项为空。

public class TypeOfViewModel
{
    /// <summary>
    /// Constructor.
    /// </summary>
    /// <param name="dependency">May be null at design time</param>
    public TypeOfViewModel(SomeDependentClass dependency)
    {

    }
}