简体   繁体   English

从 XAML 调用参数化构造函数

[英]Calling a parameterized constructor from XAML

While using WPF I noticed that when I add a control to a XAML file, the default constructor is called.在使用 WPF 时,我注意到当我向 XAML 文件添加控件时,会调用默认构造函数。

Is there a way to call a parameterized constructor?有没有办法调用参数化构造函数?

.NET 4.0 brings a new feature that challenges the answer - but apparently only for UWP applications (not WPF). .NET 4.0 带来了一项挑战答案的新功能 - 但显然仅适用于 UWP 应用程序(而非 WPF)。

x:Arguments Directive x:参数指令

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

One of the guiding principles of XAML-friendly objects is that they should be completely usable with a default constructor, ie, there is no behavior that is only accessible when using a non-default constructor. XAML 友好对象的指导原则之一是它们应该完全可用于默认构造函数,即,没有仅在使用非默认构造函数时才可访问的行为。 To fit with the declarative nature of XAML, object parameters are specified via property setters.为了适应 XAML 的声明性质,对象参数是通过属性设置器指定的。 There is also a convention that says that the order in which properties are set in XAML should not be important.还有一个约定表示在 XAML 中设置属性的顺序不重要。

You may, however, have some special considerations that are important to your implementation but at odds with convention:但是,您可能有一些对您的实现很重要但与惯例不一致的特殊注意事项:

  1. You may have one or more properties which must be set before the object can be used.您可能有一个或多个必须在使用对象之前设置的属性。
  2. Two or more properties may be mutually exclusive with each other, eg, it makes no sense to set both the StreamSource and UriSource of an image.两个或多个属性可能相互排斥,例如,同时设置图像的StreamSourceUriSource是没有意义的。
  3. You may want to ensure that a property is only set during initialization.您可能希望确保在初始化期间设置属性。
  4. One property may depend on another, which can be tricky due to the aforementioned convention of order independence when setting properties.一个属性可能依赖于另一个属性,由于在设置属性时前面提到的顺序无关约定,这可能会很棘手。

To make it easier to handle these cases, the ISupportInitialize interface is provided.为了更轻松地处理这些情况,提供了ISupportInitialize接口。 When an object is read and created from XAML (ie, parsed), objects implementing ISupportInitialize will be handled specially:当从 XAML 读取和创建对象(即解析)时,将特别处理实现ISupportInitialize对象:

  1. The default constructor will be called.将调用默认构造函数。
  2. BeginInit() will be called. BeginInit()将被调用。
  3. Properties will be set in the order they appeared in the XAML declaration.属性将按照它们在 XAML 声明中出现的顺序进行设置。
  4. EndInit() is called. EndInit()被调用。

By tracking calls to BeginInit() and EndInit() , you can handle whatever rules you need to impose, including the requirement that certain properties be set.通过跟踪对BeginInit()EndInit()调用,您可以处理您需要施加的任何规则,包括设置某些属性的要求。 This is how you should handle creation parameters;这是您应该如何处理创建参数; not by requiring constructor arguments.不是通过要求构造函数参数。

Note that ISupportInitializeNotification is also provided, which extends the above interface by adding an IsInitialized property and Initialized event.请注意,还提供了ISupportInitializeNotification ,它通过添加IsInitialized属性和Initialized事件扩展了上述接口。 I recommend using the extended version.我建议使用扩展版本。

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

Yes, you can do it by the ObjectDataProvider .是的,您可以通过ObjectDataProvider It allows you to call non-default constructor, for example:它允许您调用非默认构造函数,例如:

<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>

assuming that Person is假设 Person 是

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

Unfortunately, you cannot bind the ConstructorParameters .不幸的是,您无法绑定ConstructorParameters See some workaround here . 在此处查看一些解决方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM