在XAML中创建嵌套类的实例

39

在一个 XAML 文件中(一个 WPF UserControl),是否有一种方法可以引用另一个类 "A" 中定义的一个 内部类 "B"?

public class A
{
    public class B
    {
    }
}

类似这样:

<local:A.B ... />

这个语法不起作用,因为在类“A”中,“B”被解释为一个名为“B”的属性。

我尝试了更多奇特的语法,如“::”或“+”,但似乎都不起作用。

我目前正在使用Silverlight 4VS2010

先感谢您的帮助。


不,这是一条命令,但它可能会成为一个。 - Pragmateek
1
我对 WPF commanding 并不是非常熟悉,在这个问题的回答中,点操作符被用来获取命令:https://dev59.com/m3RB5IYBdhLWcg3wgXdV 但是,这些命令被定义在另一个类中。 - Ashley Grenon
对于业务命令来说,这确实是标准的方法,但我的命令是 UI 命令,在除了当前 UI 之外的其他上下文中无法重用。 - Pragmateek
我相信答案没有被正确标记。请参见我的问题的更新 - Gennady Vanin Геннадий Ванин
2
这不是对问题的直接回答,但我解决了一个非常相关的问题:我想将一个嵌套类实例传递给<d:Style.DataContext>标记(确切地说,没有使用d:DesignInstance标记扩展,否则VS设计器会显示错误)。然后我发现我可以指定<x:Type Type="nmspc:A+B" />,它也可以工作。也许这对某些人有帮助。 - N. Kudryavtsev
1
“.”指的是属性;不确定为什么XAML不能搜索嵌套类,但它确实不能。当嵌套类在字符串内部(例如属性值)时,可以使用“+”表示。作为元素名称(如问题所示),不允许使用“+”,因为结果将不再是有效的XML;“+”不是有效的名称字符。 - ToolmakerSteve
3个回答

56

这个问题很老了,我不知道它是否适用于2010年的WPF版本,但现在您可以通过使用嵌套类型的“真实”(内部)名称使其起作用:

<local:A+B />

如果你曾经看过反汇编的代码,嵌套类型就是这个样子:

ParentTypeName+Nested

1
似乎在Silverlight中无法工作。我收到了一个“字符'+',十六进制值为0x2B,不能包含在名称中”的解析器错误。 - jspaey
1
我不确定你所说的“真实”或“内部”的含义,但元数据并没有将封闭类的名称存储在与嵌套类的名称相同的字段中,更不用说使用“+”作为分隔符了。你看到的“+”是反汇编器添加的。 - Brian Reichle
5
具体来说,这只有在字符串内(例如属性值)才可能实现。作为元素名称(如答案中所示),是不允许的,因为结果将不再是有效的 XML;+ 不是一个有效的名称字符。 - ToolmakerSteve
它有效!有人能找到关于使用“+”的任何官方文件/文章吗?我想了解更多。 - mwck46
@kykzk46 - 你使用的确切语法是什么?你是像这个答案中所示那样在元素名称中使用它,还是像我的评论和我的答案中提到的那样在字符串中使用它?此外,你是在WPF或Xamarin Forms或其他地方使用XAML吗? - ToolmakerSteve

34
我一直在寻找答案,因为如果这是可能的话,我想知道。不幸的是,我在msdn上找到了这个:

你的自定义类不能是嵌套类(nested class)。嵌套类和它们在一般的CLR语法中使用的“点”会干扰其他WPF和/或XAML功能,例如附加属性。

因此,似乎您无法使用点运算符引用嵌套类。至于通过XAML获取内部类的替代方法,我在搜索中没有找到任何有用的信息。:o(但这是一个相当有趣的问题,所以我将继续寻找。也许我会找到一些有用的信息!:o)


谢谢你的回答。我很担心会得到这样的答案,但根据这个引用,似乎你是正确的。 - Pragmateek
这是“一般情况”,但是在我的具体代码中,我的XAML中有很多“点”。此外,它指出“自定义类不能是嵌套类”,但问题不在于自定义类是否嵌套,而在于自定义类是否包含嵌套类。 - Gennady Vanin Геннадий Ванин
我认为奇怪的是,没有像“XAML不支持嵌套类”或“不支持嵌套类”这样的警告被创建。相反,你必须自己解决问题并去Stack Overflow寻求帮助。有点烦人... - florien
但是请参见我的答案,其中提供了一种可以有时使用的解决方法。具体而言,虽然不能使元素名称成为嵌套类("."始终被解释为"属性","+"不是有效的XAML),但如果您可以组合使用嵌套类在字符串内的XAML,则可能是可行的(使用"+"代替".")。 - ToolmakerSteve

19

. 指的是一个属性;不确定为什么 XAML 不能搜索嵌套类,但它确实不能。


当嵌套类在字符串内(例如属性值)时,可以使用 A+B 代替 A.B 来表示嵌套类。

<Label SomeProperty1="{x:Static local:A+B.SomeProperty2}" />

作为元素名(如问题所示),+是不允许的,因为结果将不再是有效的XML; +不是有效的名称字符:
XAML是XML
XML规范-NameChar

因此,元素名称无法直接描述嵌套类。
但请参见下面的更新-解决此问题的另一种语法。


更新
根据@Artfunkel在一个答案中的评论,这应该是一个解决方案[我没有测试]:

<x:Type TypeName="local:A+B"/>

来源:https://learn.microsoft.com/zh-cn/dotnet/framework/xaml-services/x-type-markup-extension

如何使用该语法指定属性名称尚未确定。使用x:TypeArguments吗?


1
我使用过它,它有效,这是正确的答案。例如:<DataTemplate DataType="viewModel:MyViewModel+MyNestedViewModel"> - Orace

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接