Параметр конструктора по умолчанию в объявлении MarkupExtension

сведя этот вопрос к минимуму, рассмотрим этот класс MarkupExtension...

public class ProblemStatement : MarkupExtension
{
    private readonly string _first;
    private readonly string _second;
    public ProblemStatement(string first, string second)
    {
        _first = first;
        _second = second;
    }
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }
    public override string ToString()
    {
        return _first + _second;
    }
}

когда этот Xaml объявлен...

<Grid>
    <TextBlock Name="TextBlock1" Tag="{so:ProblemStatement 'hello', 'world'}"/>
    <TextBlock Text="{Binding ElementName=TextBlock1, Path=Tag}"/>
</Grid>

...вот видишь!--11-->helloworld ' в TextBlock, как и ожидалось. Все хорошо до этого момента.

но изменение параметра конструктора на это...

public ProblemStatement(string first, string second = "nothing")

...и соответствующий Xaml для этого...

   <Grid>
        <TextBlock Name="TextBlock1" Tag="{so:ProblemStatement 'hello'}"/>
        <TextBlock Text="{Binding ElementName=TextBlock1, Path=Tag}"/>
    </Grid>

сообщение Ошибка есть...

No constructor for type 'ProblemStatement' has 1 parameters.

существует обходной путь, который должен связать конструктор, добавив этот оператор в класс...

public ProblemStatement(string first) : this(first, "not provided") { }

и это покажет 'hellonot при условии' в TextBlock. Однако это также изменяет семантику MarkupExtension и нежелательно в более крупном, "реальном" случае. Также сложность перегрузки резко возрастает, когда используются более сложные типы или аргументы конструктора динамического типа. Также, например, использование новых атрибутов "информация о вызывающем абоненте" полностью блокируется.

Итак, вопрос: как объявить Xaml, чтобы синтаксический анализатор Xaml выполнял аргумент конструктора по умолчанию?

1 ответов


попробуйте это:

    public string Optional{ get; set; } = "DefaultValue";

    private readonly string _mandatory;

    public ProblemStatement(string mandatory)
    {
        _mandatory = mandatory;
    }

использование:

<TextBlock Name="TextBlock1" Tag="{local:ProblemStatement 'hello', Optional=NotDefault}"/>

альтернатива:

<TextBlock Name="TextBlock1" Tag="{local:ProblemStatement 'hello'}"/>

результат:

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