Creating an instance of a nested class in XAML
Asked Answered
G

3

38

in a XAML file (a WPF UserControl), is there a way to reference an inner class "B" defined in another class "A" ?

public class A
{
    public class B
    {
    }
}

Something like :

<local:A.B ... />

This syntax does not work because "B" is interpreted as a property named "B" in class "A".

I've tried more exotic syntaxes like "::" or "+" but none seems to work.

I'm currently using Silverlight 4 with VS2010.

Thanks in advance for your help.

Gossamer answered 24/11, 2010 at 17:49 Comment(6)
No it's a command, but could be.Gossamer
I'm not terribly familiar with WPF commanding, in the answer to this question, the dot operator is used to get the command: https://mcmap.net/q/344377/-how-do-i-add-a-custom-routed-command-in-wpf But, the commands are defined in a different class.Claudicant
For business command this is indeed the standard approach but my command here are UI commands that are not reusable in another context than my current UI.Gossamer
I do believe that the answer was not marked correctly. See update to my questionClaycomb
It isn't a direct answer to the question but I solved a very related issue: I wanted to pass a nested class instance to <d:Style.DataContext> tag (exactly without d:DesignInstance markup extension because otherwise VS designer shows errors). Then I figured out I can specify <x:Type Type="nmspc:A+B" /> instead and it will work too. Maybe this will be helpful for someone.Aparicio
. refers to a property; not sure why XAML couldn't also search for a nested class, but it doesn't. A nested class can be represented when inside a string (e.g. a property value), using + instead of .. As an element name (as shown in question), + is not allowed, as the result would no longer be valid XML; + is not a valid name character.Kush
C
33

I was searching and searching, because if this is possible, I would like to know. Unfortunately, I found this on msdn:

Your custom class must not be a nested class. Nested classes and the "dot" in their general CLR usage syntax interfere with other WPF and/or XAML features such as attached properties.

So, it appears you can't reference a nested class with the dot operator. As for alternative ways of getting to that inner class through XAML, I haven't had any luck in my searches yet. :o( But this is a rather interesting issue, so I will continue searching. Maybe I'll find some luck! :o)

Claudicant answered 24/11, 2010 at 18:44 Comment(4)
Thanks for your answer. I was afraid of this kind of answer but according to this quote it seems you are right.Gossamer
This is "in general" but in my concrete code I have a lot of "dots" in my XAML. Besides, it tells that "custom class must not be a nested class" but the question is not about custom class being nested but about custom class containing nested classClaycomb
What I consider strange is that there is no such warning created like "XAML does not support nested classes" or "nested classes are not supported". Instead, you have to figure it out and go to Stack Overflow this. Bit annoying...Needlepoint
But see my answer for a work-around that can sometimes be used. Specifically, while it is true that you can't make an element name be a nested class ("." is always interpreted as "property of", and "+" would not be valid XAML), if you can compose XAML that uses the nested class inside a string, then it may be possible (using "+" instead of ".").Kush
V
56

This question is pretty old, and I don't know if it would have worked with the version of WPF back in 2010, but now you can make it work by using the "real" (internal) name of the nested type:

<local:A+B />

If you've ever looked a disassembled code, that's how nested types look like:

ParentTypeName+Nested
Volatilize answered 14/11, 2012 at 0:9 Comment(5)
Doesn't appear to work in Silverlight. I get a 'The '+' character, hexadecimal value 0x2B, cannot be included in a name' parser error.Fortenberry
I'm not sure what you mean by "real" or "internal" but the metadata does not store the name of the enclosing class in the same field as the name of the nested class, let alone use '+' as a separator. The '+' you see is added by the disassembler.Colourable
Specifically, this is possible when inside a string (e.g. a property value). As an element name (as shown in answer), it is not allowed, as the result would no longer be valid XML; + is not a valid name character.Kush
It works!. Could anyone find any official document / article about the usage of +? I would like to know moreAiry
@kykzk46 - what is the exact syntax that you used? Did you use it in an element name as shown in this answer, or in a string, as mentioned in my comment and my answer? Also, did you use XAML in WPF or Xamarin Forms or somewhere else?Kush
C
33

I was searching and searching, because if this is possible, I would like to know. Unfortunately, I found this on msdn:

Your custom class must not be a nested class. Nested classes and the "dot" in their general CLR usage syntax interfere with other WPF and/or XAML features such as attached properties.

So, it appears you can't reference a nested class with the dot operator. As for alternative ways of getting to that inner class through XAML, I haven't had any luck in my searches yet. :o( But this is a rather interesting issue, so I will continue searching. Maybe I'll find some luck! :o)

Claudicant answered 24/11, 2010 at 18:44 Comment(4)
Thanks for your answer. I was afraid of this kind of answer but according to this quote it seems you are right.Gossamer
This is "in general" but in my concrete code I have a lot of "dots" in my XAML. Besides, it tells that "custom class must not be a nested class" but the question is not about custom class being nested but about custom class containing nested classClaycomb
What I consider strange is that there is no such warning created like "XAML does not support nested classes" or "nested classes are not supported". Instead, you have to figure it out and go to Stack Overflow this. Bit annoying...Needlepoint
But see my answer for a work-around that can sometimes be used. Specifically, while it is true that you can't make an element name be a nested class ("." is always interpreted as "property of", and "+" would not be valid XAML), if you can compose XAML that uses the nested class inside a string, then it may be possible (using "+" instead of ".").Kush
K
19

. refers to a property; not sure why XAML couldn't also search for a nested class, but it doesn't.


A nested class can be represented when inside a string (e.g. a property value), using A+B instead of A.B:

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

As an element name (as shown in question), + is not allowed, as the result would no longer be valid XML; + is not a valid name character:
XAML is XML.
XML Spec - NameChar.

So the element name cannot directly describe a nested class.
BUT see UPDATE below - an alternative syntax that solves this.


UPDATE
Per @Artfunkel's comment on one answer, this should be a solution [I have not tested]:

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

From: https://learn.microsoft.com/en-us/dotnet/framework/xaml-services/x-type-markup-extension

TBD how to specify property name with that syntax. Use x:TypeArguments?

Kush answered 24/6, 2018 at 2:43 Comment(1)
I used it, it works, this is the correct answer. Ex:<DataTemplate DataType="viewModel:MyViewModel+MyNestedViewModel">Ernaernald

© 2022 - 2024 — McMap. All rights reserved.