将此问题减少到最低限度,请考虑此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>
...您可以按预期在TextBlock中看到“ helloworld ”。一切都很顺利。
但是将构造函数参数更改为此...
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") { }
这将在TextBlock中显示“ hellonot提供”。然而,这也改变了MarkupExtension的语义,并且在更大的“真实世界”情况下是不可取的。当使用更复杂的类型或构造函数参数的类型为“dynamic”时,重载的复杂性也会显着增加。此外,例如,完全阻止使用新的“来电者信息”属性。
所以问题是:如何声明Xaml以便Xaml解析器遵循默认的构造函数参数?
答案 0 :(得分:9)
试试这个:
curl
用法:
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}"/>
结果: