MarkupExtension声明中的默认构造函数参数

Gay*_*Fow 10 c# wpf xaml markup-extensions

将此问题减少到最低限度,请考虑此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;
    }
}
Run Code Online (Sandbox Code Playgroud)

宣布这个Xaml时......

<Grid>
    <TextBlock Name="TextBlock1" Tag="{so:ProblemStatement 'hello', 'world'}"/>
    <TextBlock Text="{Binding ElementName=TextBlock1, Path=Tag}"/>
</Grid>
Run Code Online (Sandbox Code Playgroud)

...你按预期在TextBlock中看到' helloworld '.一切都很顺利.

但是将构造函数参数更改为此...

public ProblemStatement(string first, string second = "nothing")
Run Code Online (Sandbox Code Playgroud)

......以及相关的Xaml ......

   <Grid>
        <TextBlock Name="TextBlock1" Tag="{so:ProblemStatement 'hello'}"/>
        <TextBlock Text="{Binding ElementName=TextBlock1, Path=Tag}"/>
    </Grid>
Run Code Online (Sandbox Code Playgroud)

生成的错误消息是......

No constructor for type 'ProblemStatement' has 1 parameters.
Run Code Online (Sandbox Code Playgroud)

有一种解决方法,即通过将此语句添加到类中来链接构造函数...

public ProblemStatement(string first) : this(first, "not provided") { }
Run Code Online (Sandbox Code Playgroud)

这将在TextBlock中显示' hellonot提供 '.然而,这也改变了MarkupExtension的语义,并且在更大的"真实世界"情况下是不可取的.当使用更复杂的类型或构造函数参数的类型为"dynamic"时,重载的复杂性也会显着增加.此外,例如,完全阻止使用新的"来电者信息"属性.

所以问题是:如何声明Xaml以便Xaml解析器遵循默认的构造函数参数?

Eya*_*rry 9

试试这个:

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

    private readonly string _mandatory;

    public ProblemStatement(string mandatory)
    {
        _mandatory = mandatory;
    }
Run Code Online (Sandbox Code Playgroud)

用法:

<TextBlock Name="TextBlock1" Tag="{local:ProblemStatement 'hello', Optional=NotDefault}"/>
Run Code Online (Sandbox Code Playgroud)

替代方案:

<TextBlock Name="TextBlock1" Tag="{local:ProblemStatement 'hello'}"/>
Run Code Online (Sandbox Code Playgroud)

结果:

  • 没有XAML解析错误
  • 无需为可选参数重载构造函数
  • 必需参数是构造函数参数.
  • 可选参数是属性.