【问题标题】:Default Constructor Parameter in MarkupExtension declarationMarkupExtension 声明中的默认构造函数参数
【发布时间】:2014-07-05 21:24:25
【问题描述】:

尽量减少这个问题,考虑这个 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 provided”。然而,这也改变了 MarkupExtension 的语义,并且在更大的“真实世界”情况下是不可取的。当使用更复杂的类型或构造函数参数是“动态”类型时,重载的复杂性也会显着增加。此外,例如,完全禁止使用新的“来电者信息”属性。

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

【问题讨论】:

    标签: c# wpf xaml markup-extensions


    【解决方案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 解析错误
    • 不需要为可选参数重载构造函数
    • 强制参数是构造函数参数。
    • 可选参数是属性。

    【讨论】:

    • ConstructorArgumentAttribute 在这种情况下提供了什么好处,因为名为 Optional 的属性实际上不是构造函数参数?我认为ConstructorArgumentAttribute 旨在更好地告知 XAML 序列化实际构造函数 arg 和属性之间的关系。
    • @AdamCaviness 没有。当时我对这个属性有错误的印象。答案已相应编辑。
    猜你喜欢
    • 1970-01-01
    • 2012-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-10
    • 2016-07-03
    • 1970-01-01
    • 2012-06-30
    相关资源
    最近更新 更多