wpf 从 XAML 调用参数化构造函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1083159/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Calling a parameterized constructor from XAML
提问by Hani
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?
有没有办法调用参数化构造函数?
回答by Raskal
.NET 4.0 brings a new feature that challenges the answer - but apparently only for UWP applications (not WPF).
.NET 4.0 带来了一项挑战答案的新功能 - 但显然仅适用于 UWP 应用程序(而非 WPF)。
<object ...>
<x:Arguments>
oneOrMoreObjectElements
</x:Arguments>
</object>
回答by Mike Strobel
One of the guiding principles of XAML-friendly objects is that they should be completely usable with a default constructor, i.e., there is no behavior that is only accessible when using a non-default constructor. To fit with the declarative nature of XAML, object parameters are specified via property setters. There is also a convention that says that the order in which properties are set in XAML should not be important.
XAML 友好对象的指导原则之一是它们应该完全可用于默认构造函数,即,没有仅在使用非默认构造函数时才可访问的行为。为了适应 XAML 的声明性质,对象参数是通过属性设置器指定的。还有一个约定表示在 XAML 中设置属性的顺序不重要。
You may, however, have some special considerations that are important to your implementation but at odds with convention:
但是,您可能有一些对您的实现很重要但与惯例不一致的特殊注意事项:
- You may have one or more properties which mustbe set before the object can be used.
- Two or more properties may be mutually exclusive with each other, e.g., it makes no sense to set both the
StreamSource
andUriSource
of an image. - You may want to ensure that a property is onlyset during initialization.
- One property may depend on another, which can be tricky due to the aforementioned convention of order independence when setting properties.
- 您可能有一个或多个必须在使用对象之前设置的属性。
- 两个或多个属性可能相互排斥,例如,设置图像的
StreamSource
和UriSource
是没有意义的。 - 您可能希望确保仅在初始化期间设置属性。
- 一个属性可能依赖于另一个属性,由于在设置属性时前面提到的顺序无关约定,这可能会很棘手。
To make it easier to handle these cases, the ISupportInitialize
interface is provided. When an object is read and created from XAML (i.e., parsed), objects implementing ISupportInitialize
will be handled specially:
为了更容易处理这些情况,ISupportInitialize
提供了接口。当从 XAML 读取和创建对象(即解析)时,对象实现ISupportInitialize
将被特殊处理:
- The default constructor will be called.
BeginInit()
will be called.- Properties will be set in the order they appeared in the XAML declaration.
EndInit()
is called.
- 将调用默认构造函数。
BeginInit()
将被调用。- 属性将按照它们在 XAML 声明中出现的顺序进行设置。
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. This is how you should handle creation parameters; not by requiring constructor arguments.
通过跟踪对BeginInit()
和 的调用EndInit()
,您可以处理您需要施加的任何规则,包括设置某些属性的要求。这是您应该如何处理创建参数;不是通过要求构造函数参数。
Note that ISupportInitializeNotification
is also provided, which extends the above interface by adding an IsInitialized
property and Initialized
event. I recommend using the extended version.
请注意,ISupportInitializeNotification
还提供了,它通过添加IsInitialized
属性和Initialized
事件扩展了上述接口。我建议使用扩展版本。
回答by Alun Harford
No. Not from XAML [when using WPF].
不。不是来自 XAML [使用 WPF 时]。
回答by chviLadislav
Yes, you can do it by the ObjectDataProvider
. It allows you to call non default constructor, for example:
是的,您可以通过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>
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
. See some workaround here.
不幸的是,您无法绑定ConstructorParameters
. 在此处查看一些解决方法。