32

I have list of items that I want to display in Canvas using data binding.

ItemsToShowInCanvas = new ObservableCollection<ItemDetail>
   {
       new ItemDetail {Text = "ABC", Top = 10, Left = 200},
       new ItemDetail {Text = "DEF", Top = 100, Left = 300},
       new ItemDetail {Text = "PQR", Top = 50, Left = 150}
   };

ItemDetail is a simple class with auto properties for Text, Top and Left values

public class ItemDetail
{
    public string Text { get; set; }
    public double Top { get; set; }
    public double Left { get; set; }
}

When I databind the items, they do appear in canvas. But the items do not appear at positions mentioned using Top and Left properties.

<Canvas>
    <ItemsControl ItemsSource="{Binding Path=ItemsToShowInCanvas}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Path=Text}" Canvas.Top="{Binding Path=Top}" Canvas.Left="{Binding Path=Left}"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Canvas>
SmiLe
  • 311
  • 2
  • 13
Souvik Basu
  • 3,069
  • 4
  • 28
  • 42
  • 2
    ItemsControl uses Stackpanel as default itemspanel. the textblock you are adding is actually adding to a stackpanel but not to canvas. The ItemsControl is adding to canvas. Try changing itemspanel to canvas – Bathineni Aug 24 '11 at 14:51
  • Thanks for the answer bathineni. I tried putting ItemsPanel as Canvas but it didnt work. The items started showing one over the other. Adding the ItemContainerStyle worked. – Souvik Basu Aug 24 '11 at 15:07
  • possible duplicate of [WPF: Is it possible to bind a Canvas's Children property in XAML?](http://stackoverflow.com/questions/889825/wpf-is-it-possible-to-bind-a-canvass-children-property-in-xaml) – H.B. Aug 24 '11 at 15:34
  • @H.B. Definetely duplicate. On the other hand, possible duplicates: http://stackoverflow.com/questions/1265364/setting-canvas-properties-in-an-itemscontrol-datatemplate http://stackoverflow.com/questions/2415580/when-using-itemscontrol-itemscontrol-itemspanel-is-set-to-canvas-contenpresenter http://stackoverflow.com/questions/4708151/how-to-convert-x-y-position-to-canvas-left-top-properties-when-using-itemscontrol http://stackoverflow.com/questions/5261640/how-can-i-position-viewmodels-in-an-itemscontrol. Feels like every question here has been answered at least 10 times :) – Fredrik Hedblad Aug 24 '11 at 19:53

1 Answers1

49

Set the ItemsPanel to a Canvas and bind the containers instead of the TextBlock in the DataTemplate

<ItemsControl ItemsSource="{Binding Path=ItemsToShowInCanvas}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="Canvas.Left" Value="{Binding Left}"/>
            <Setter Property="Canvas.Top" Value="{Binding Top}"/>
        </Style>
    </ItemsControl.ItemContainerStyle>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=Text}" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
Fredrik Hedblad
  • 83,499
  • 23
  • 264
  • 266