-2

Following shows part of my MainWindow.xaml:

<Grid>
    <ListBox x:Name="listBox"                          (Line #40)
        ItemsSource="{Binding Rectangles}"
        SelectionMode="Extended" >
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas />
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
        <ListBox.ItemContainerStyle>
            <Style
                TargetType="{x:Type ListBoxItem}" >
                <Setter
                    Property="Canvas.Left"
                    Value="{Binding X}" />
                <Setter
                    Property="Canvas.Top"
                    Value="{Binding Y}" />
            </Style>
        </ListBox.ItemContainerStyle>
    </ListBox>
    <Canvas x:Name="dragSelectionCanvas"               (Line #64)
        Visibility="Collapsed" >
        <Border x:Name="dragSelectionBorder"           (Line #66)
            Opacity="0.5" />
    </Canvas>
</Grid>

And this is the corresponding MainWindow.g.i.cs file generated by Visual Studio:

public partial class MainWindow : System.Windows.Window, System.Windows.Markup.IComponentConnector {

    #line 40 "..\..\MainWindow.xaml"
    internal System.Windows.Controls.ListBox listBox;

    #line 64 "..\..\MainWindow.xaml"
    internal System.Windows.Controls.Canvas dragSelectionCanvas;

    #line 66 "..\..\MainWindow.xaml"
    internal System.Windows.Controls.Border dragSelectionBorder;

(I have deleted some lines for sake of brevity.)

I can see in the .cs file that for every XAML element with an x:Name attribute, Visual Studio generates a corresponding member declaration.

My question: Where are the declarations for those XAML elements, such as the Grid element above as well as the outer Window element (not shown) that do not have an x:Name attribute? Are they declared as well behind the scenes?

Sabuncu
  • 5,095
  • 5
  • 55
  • 89

1 Answers1

1

They aren't declared anywhere.

XAML code like this:

<Canvas x:Name="dragSelectionCanvas"               (Line #64)
    Visibility="Collapsed" >
    <Border x:Name="dragSelectionBorder"           (Line #66)
        Opacity="0.5" />
</Canvas>

equals

new Canvas
{
    Visibility = Visibility.Collapsed,
    Content = new Border { Opacity = 0.5 }
}

You only need a reference to the root control which is this in your xaml.cs class. Things with names are just shortcut references to those object, so that you don't need to go down the logical tree every time.

Once you understand that <SomeClass Property="5"/> == new SomeClass { Property = 5 } everything becomes easier.

For example, in MVVM you set up ViewModel property. You can it in xaml.cs in constructor:

this.ViewModel = new SpecificViewModel() - if it has default contructor

or in xaml:

<MyControl.ViewModel> <SpecificViewModel/> </MyControl.ViewModel>

This basically means, that you can contruct fully speced UserControl in only cs file like this:

public class MyControl : UserControl
{
    public MyControl()
    {
       Content = new StackPanel { Content = new TextBlock{ Text = "Sample Text"}};
    }
}

Notice that the TextBlock isn't referenced anywhere, but it's still there. Analogical xaml should be now straight forward to write.

You probably noticed the lack off InitializeComponents() call. That's because under the hood it runs the generated from XAML and fills this.Content and sets references to objects with names. No XAML means no need to call this method.

You can find more details here

Krzysztof Skowronek
  • 2,796
  • 1
  • 13
  • 29
  • Where is the code for `new Canvas { Visibility = ... ` kept? What file is it in? Thanks. – Sabuncu Apr 10 '20 at 14:25
  • I added something about `InitializeComponents` - this is the key to your mistery :) – Krzysztof Skowronek Apr 10 '20 at 14:26
  • Basically, XAML is converted straight to object tree inside `InittailizeComponents` call – Krzysztof Skowronek Apr 10 '20 at 14:31
  • 1
    I see. Object tree that we can't see, nothing generated in code. Thank you. – Sabuncu Apr 10 '20 at 14:32
  • "Things with names are just shortcut references". names are unique identifiers, which also happen to be "shortcut references" because there is some autogenerated code which uses them. But names can be also used to obtain references at runtime from control/template, to create bindings, etc – ASh Apr 10 '20 at 16:28