Подтвердить что ты не робот

Как использовать d: DesignInstance с типами, которые не имеют конструктора по умолчанию?

Я привязываю текстовое поле к объекту, например:

  <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, я получаю конструктор "Нет по умолчанию".

Я знаю, что когда я использую d:DataContext="{d:DesignInstance ViewModel:TaskVM }", он создает макет данных. Есть ли способ установить свойства этого макетного типа?

Спасибо!

4b9b3361

Ответ 1

Конструктор по умолчанию требуется для типа, который будет создан в 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>

Ответ 2

Вы можете добавить конструктор по умолчанию к своей виртуальной машине. Затем он может проверить, находится ли он во время разработки, и установить соответствующие значения времени разработки для его свойств.

Ответ 3

Другой альтернативой было бы использование статического класса для хранения модели представления и вызова этого класса из XAML. Вот пример:

Для создания контекста данных дизайна xaml использует модель представления factory:

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 должен быть реализован таким образом, что ему известно, что во время проектирования прошедшая в зависимостях значение null.

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

    }
}