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


Answers:


74

.NET 4.0带来了一个新功能,该功能对答案提出了挑战-但显然仅适用于UWP应用程序(而非WPF)。

x:参数指令

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

很好,很高兴您提出来。
杰夫·梅卡多

33
:对于谁比谁来到这里寻找的正是这种答案,我会因为你要找到下一个这篇文章为你节省时间stackoverflow.com/questions/14347181/...
Kevek

6
“基本上没有当前的编译器(WPF,SL,WinRT)实际上支持它”-Duncan Matheson。由凯维克的评论链接,应该在答案中。
戴维(David

x名称空间定义为什么?
jpmc26,2016年

3
不幸的是,该语法适用于XAML 2009版本,这意味着通用应用程序,并且可悲地在WPF中无法使用。
阿米尔·马赫迪·纳西里

30

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

但是,您可能需要考虑一些特殊的注意事项,这些注意事项对于您的实现很重要,但与约定不符:

  1. 您可能具有一个或多个必须使用对象才能设置的属性。
  2. 两个或多个属性可能彼此互斥,例如,设置图像的StreamSource和都没有意义UriSource
  3. 您可能要确保在初始化期间设置属性。
  4. 一个属性可能依赖于另一个属性,由于设置属性时前面提到的顺序独立性约定,这可能会很棘手。

为了更轻松地处理这些情况,ISupportInitialize提供了接口。从XAML读取和创建对象(即已解析)时,ISupportInitialize将特别处理实现对象:

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

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

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



7

是的,您可以在旁进行操作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>

假设该人是

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.