从XAML调用参数化构造函数

Han*_*ani 58 wpf xaml

在使用WPF时,我注意到当我将控件添加到XAML文件时,会调用默认构造函数.

有没有办法调用参数化构造函数?

小智 73

.NET 4.0带来了一个挑战答案的新功能.

x:参数指令

<object ...>
    <x:Arguments>
        oneOrMoreObjectElements
    </x:Arguments>
</object>
Run Code Online (Sandbox Code Playgroud)

  • 对于那些来这里寻找这个答案的人来说,我会节省你一些时间,因为你将在下一篇文章中找到这篇文章:http://stackoverflow.com/questions/14347181/how-to-fix-xaml2009-语言结构 - 是 - 不是允许的,在这里 (30认同)
  • "基本上没有当前的编译器(WPF,SL,WinRT)实际上支持它" - Duncan Matheson.由Kevek的评论联系起来,应该在答案中. (5认同)
  • 不幸的是,此语法适用于 XAML 2009 版本,这意味着通用应用程序,并且在 WPF 中不起作用。 (3认同)

Mik*_*bel 27

我知道我在这里参加派对已经迟到了,但由于没有人真正解决WPF的惯例,我以为我会参与其中.

XAML友好对象的指导原则之一是它们应该完全可以使用默认构造函数,即,没有只有在使用非默认构造函数时才能访问的行为.为了适应XAML的声明性质,通过属性设置器指定对象参数.还有一个约定规定,在XAML中设置属性的顺序不应该很重要.

但是,您可能会有一些对您的实现很重要的特殊注意事项,但与惯例不一致:

  1. 在使用对象之前,您可能必须设置一个或多个属性.
  2. 两个或更多个属性可以彼此互斥,例如,设置图像StreamSourceUriSource图像都没有意义.
  3. 您可能希望确保在初始化期间设置属性.
  4. 一个属性可能依赖于另一个属性,由于上述设置属性时的顺序独立性约定,这可能是棘手的.

为了更容易处理这些情况,ISupportInitialize提供了界面.当从XAML读取和创建对象(即解析)时,ISupportInitialize将专门处理实现的对象:

  1. 将调用默认构造函数.
  2. BeginInit() 将被召唤.
  3. 属性将按照它们在XAML声明中出现的顺序进行设置.
  4. EndInit() 叫做.

通过跟踪对BeginInit()和的调用EndInit(),您可以处理需要施加的任何规则,包括设置某些属性的要求.这是你应该如何处理创建参数; 不要求构造函数参数.

请注意,ISupportInitializeNotification还提供了通过添加IsInitialized属性和Initialized事件来扩展上述接口.我建议使用扩展版本.


Alu*_*ord 11

不.不是来自XAML [使用WPF时].


chv*_*lav 8

是的,您可以通过ObjectDataProvider. 它允许您调用非默认构造函数,例如:

<Grid>
    <Grid.Resources>
        <ObjectDataProvider x:Key="myDataSource"
                            ObjectType="{x:Type local:Person}">
            <ObjectDataProvider.ConstructorParameters>
                <system:String>Joe</system:String>
            </ObjectDataProvider.ConstructorParameters>
        </ObjectDataProvider>
    </Grid.Resources>
    <Label Content="{Binding Source={StaticResource myDataSource}, Path=Name}"></Label>
</Grid>
Run Code Online (Sandbox Code Playgroud)

假设 Person 是

public class Person
{
    public Person(string Name)
    {
        this.Name = Name;
    }
    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,您无法绑定ConstructorParameters. 在此处查看一些解决方法。