To build on what others have said here is a complete self contained example - you can copy it straight into kaxaml or xamlpad (or blend, but I think in that case it has to go into a body of a usercontrol or a window) and see how it works.
Instead of using the rendertransform I prefer to use the canvas and set the left and top property, I just find it more readable that way. Alternatively, you can use a grid and set the margin but then you ll need a value converter of some kind.
<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid.Resources>
<!-- This is our list of shapes, in this case an inline XML list -->
<XmlDataProvider x:Key="ShapeList">
<x:XData>
<ObjectList xmlns="">
<Shapes>
<shape height="30" width="30" x="50" y="50"/>
<shape height="30" width="40" x="100" y="100"/>
<shape height="30" width="50" x="150" y="150"/>
<shape height="30" width="60" x="200" y="200"/>
<shape height="30" width="70" x="250" y="350"/>
</Shapes>
</ObjectList>
</x:XData>
</XmlDataProvider>
</Grid.Resources>
<ItemsControl ItemsSource="{Binding Source={StaticResource ShapeList}, XPath=ObjectList/Shapes/*}">
<!-- this template sets the panel as canvas for easy positioning -->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas IsItemsHost="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!-- this template defines how each bound item is represented -->
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Width="{Binding XPath=@width}" Height="{Binding XPath=@height}">
<Ellipse Fill="White" Stroke="Black" StrokeThickness="2"/>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
<!-- This style positions each bound item s container -->
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Left" Value="{Binding XPath=@x}"/>
<Setter Property="Canvas.Top" Value="{Binding XPath=@y}"/>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</Grid>
Instead of binding to an inline xml list you can bind to a collection on your viewmodel (best choice), a dependency property on your control or window, set the resource from codebehind, etc.
The key point is that you shouldn t be laying out the ellipses in C# unless you absolutely have to. Provide the data as some sort of a list of meaningful objects. Then create a data template that defines how that data is represented. Assuming you don t have to do any sort of complicated processing of your object to get the relevant ellipse properties you should be able to do this without any code, or at most with a few value converters.
This is the sort of UI separation that allows you to deal with updating the datasource (business logic) and displaying items (ui) separately.
So basically the idea is:
- Expose a collection of objects - in my example this would be a collection of classes mirroring the structure of the shape xml element in the list. This can be the business object itself, or a viewmodel - a class that wraps a business objects and exposes conveniently bindable properties (in this case, position and size). The collection itself would prefereably be an ObservableCollection, so that UI is notified when you add or remove objects. Toss in some design time data into it if possible.
- Bind to the collection, using the WPF datatemplates to define how an element should be presented. In this case I used a plain ItemsControl with a few simple templates, but this can be as complex as required
- Work out how the collection will be updated from the original datasource. If you set up the previous steps correctly this is essentially a separate problem