从XAML调用参数化的构造函数

在使用WPF时,我注意到当我将一个控件添加到一个XAML文件时,默认的构造函数被调用。

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

.NET 4.0带来了一个挑战答案的新function。

x:参数指令

<object ...> <x:Arguments> oneOrMoreObjectElements </x:Arguments> </object> 

我意识到我迟到了这里的派对,但是由于没有人真的讨论过WPF的会议,我以为我会插话。

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

但是,您可能会有一些特殊的考虑因素,这些考虑因素对您的实施很重要,但与公约不一致:

  1. 您可能有一个或多个属性, 必须先设置对象才能使用。
  2. 两个或多个属性可能互相排斥,例如,设置图像的StreamSourceUriSource都是没有意义的。
  3. 您可能希望确保在初始化期间设置属性。
  4. 一个属性可能依赖于另一个属性,由于前面提到的设置属性时的顺序独立性的惯例,这可能是棘手的。

为了更容易处理这些情况,提供了ISupportInitialize接口。 当从XAML(即parsing)读取和创build对象时,实现ISupportInitialize对象将被专门处理:

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

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

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

不是,从XAML [使用WPF时]。

是的,你可以通过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> 

假设Person是

 public class Person { public Person(string Name) { this.Name = Name; } public string Name { get; set; } } 

不幸的是,你不能绑定ConstructorParameters 。 在这里看到一些解决方法。