Home > View Post

Using Binding to position a Collection of elements

UPDATE - here's a much better way to solve this: Using Binding to position a Collection of elements - Take 2 I was recently looking at a WPF query with my new colleague Simon Ince (check out his first MSDN blog post on CTE in SQL 2005).

The question was along the lines of "How can I position a collection of elements on a canvas using databinding? The number of elements is unknown at design time".

Wherever we have an unknown number of items in a collection your attention is normally going to turn to using an ItemsControl. In this case we'd probably want to swap the ItemsPanel for a Canvas and then we can databind away, right?

Here's an example in pure Xaml. Note that we create an array of System.Drawing.Points in Xaml to bind to.


        <x:Array x:Key="myArray" Type="{x:Type draw:Point}">
            <draw:Point X="10" Y="20"/>
            <draw:Point X="20" Y="10"/>
            <draw:Point X="30" Y="50"/>

    <ItemsControl ItemsSource="{Binding Source={StaticResource myArray}, Path=.}">
                <Rectangle Canvas.Top="{Binding Y}" Canvas.Left="{Binding X}" Fill="Red" Width="10" Height="10"/>
                <Canvas IsItemsHost="True" />


However, as you can see from the render in XamlPad, this isn't working. The visual tree shows why...

xamlpad render

The ItemsControl wraps each item in a ContentPresenter and, as you know, Canvas's attached Top and Left properties only work on direct children of the canvas. Time for another approach.

Let's use a transform, a translate transform to be specific.

<Rectangle Fill="Red" Width="10" Height="10">
        <TranslateTransform X="{Binding X}" Y="{Binding Y}" />

working xamlpad render

That's better.

Another option would be to modify the Margin of the rectangle something like this:

<Rectangle Fill="Red" Width="10" Height="10">
        <Thickness Left="{Binding X}" Top="{Binding Y}" />

Of course this won't work because the Thickness's Left and Top properties aren't DependencyProperties and therefore can't be the target of a binding. That doesn't rule this out as an option, you'd just have to write an IMultiValueConverter and a MultiBinding as discussed at the end of Reason 2. Databinding.

Tags: WPF

Josh Post By Josh Twist
5:39 AM
31 Oct 2007

» Next Post: Reason 6. Layout
« Previous Post: Binding to Attached Properties

Comments are closed for this post.

Posted by Peter @ 08 Sep 2008 2:54 PM
Do you know of any code that illustrates a bar graph that uses adorners to adjust the bars by dragging? Additionally, I would like the polys bound so as they adjust, their positions can be used via convertors to determine their X/Y values?


© 2005 - 2022 Josh Twist - All Rights Reserved.