tags:

views:

61

answers:

2
+1  Q: 

Binding to Canvas

I have a canvas property in my class and I was wondering if it's possible to bind that to a canvas in xaml?

How would the databinding work in the canvas?

<Canvas ItemSource="{Binding ClassCanvas}" />
A: 

Yes.

You can bind to a canvas or any other object.

SLaks
So I can have a canvas object in my class and bind that to the canvas in the xaml? How would the data binding work on that? Can I add children to the canvas in the class and that would change in the xaml?
Robert
You can set the `Canvas` object on your class to refer to the canvas in your XAML.
SLaks
A: 

If you want your Canvas defined in XAML to include the entire Canvas in your class as a single item you can write:

<Canvas>
  <ContentPresenter Content="{Binding ClassCanvas}" />
  ... other items here ...
</Canvas>

If you want your Canvas defined in XAML to include all the same UIElements as the Canvas defined in your class, it is impossible because a UIElement can have only one UIElement parent. So if the Canvas defined in the class is the parent of a given UIElement, the Canvas defined in XAML can't be.

If you want your Canvas to display data from each UIElement in the Canvas defined in your class, you can do this with an ItemsControl with a Canvas panel and a DataTemplate:

<ItemsControl ItemsSource="{Binding ClassCanvas.Children}">
  <ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
      <Canvas />
    </ItemsPanelTemplate>
  </ItemsControl>
  <ItemsControl.ItemsContainerStyle>
    <Style>
      <Setter Property="Canvas.Left" Value="{Binding (Canvas.Left)}" />
      <Setter Property="Canvas.Left" Value="{Binding (Canvas.Top)}" />
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate>
            ... display of UIElement here, either using VisualBrush or custom display
          </ControlTemplate>
        <Setter.Value>
      </Setter>
    </Style>
  </ItemsControl.ItemsContainerStyle>
</ItemsControl>

Note that this code will only scan the Children property once since it is not an INotifyCollectionChanged collection.

If you want to bind to a property in your class that contains a collection of UIElements with their Canvas.Top and Canvas.Left properties set, you can easily do this if the container is an ObservableCollection instead of a Canvas.

The Canvas class was never designed for use within your data layer. I would strongly recommend you switch to using an ObservableCollection there and only use Canvas as part of your view.

Ray Burns