Pregunta

I have the following working XAML code:

<Window x:Class="DrawShape.Window1"
    ...
    <Grid>
        <Polygon Name="poly"/>
    </Grid>           
</Window>

In the corresponding C# code, a static callback method (for a property called Sides) accesses the poly element as follows:

static void OnSidesChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
    Window1 win = obj as Window1;

    win.poly.Points.Clear();
    ...

How is it that poly is accessed directly through Window1 win? poly is nested within a Grid element (albeit nameless). Is this type of access a feature of WPF?

PS: I am aware about the need for access through an object (because the method is static), it is the nesting that I don't understand.

¿Fue útil?

Solución

You are confusing the WPF logical tree with how names are handled in XAML. In the logical tree the Polygon is contained in the Grid. However, all names belong to the same scope and are available as fields in the class generated from the XAML.

However, WPF has the concept of Namescopes which makes it possible to use the same name in multiple scopes.

Styles and templates in WPF provide the ability to reuse and reapply content in a straightforward way. However, styles and templates might also include elements with XAML names defined at the template level. That same template might be used multiple times in a page. For this reason, styles and templates both define their own XAML namescopes, independent of whatever location in an object tree where the style or template is applied.

In the simple XAML below you have a Grid named grid containing a ListBox named listBox. In the class generated from the XAML there are fields named grid and listBox allowing the code behind to access both controls.

Each list box item generated by the ItemTemplate contains a TextBlock named textBlock. However, each list box item is in a separate Namescope and there is no field named textBlock in the class generated from the XAML.

<Grid x:Name="grid">
  <ListBox x:Name="listBox">
    <ListBox.ItemTemplate>
      <DataTemplate>
        <StackPanel Orientation="Horizontal">
          <TextBlock x:Name="textBlock" Text="{Binding Name}"/>
        </StackPanel>
      </DataTemplate>
    </ListBox.ItemTemplate>
  </ListBox>
</Grid>

In this simple example there is no need to name the TextBlock objects. However, in more advanced scenarios you may want to refer to named elements within the template, e.g. in triggers.

Otros consejos

Locate the file Window1.g.cs in your project directory.

Window1.g.cs contains a partial class that was generated from your XAML. In there you find the variable definition for poly.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top