How to display items in Canvas through Binding

21,872

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>
Share:
21,872
Souvik Basu
Author by

Souvik Basu

Hobbyist programmer since Y2K bug (1999), coding professionally since 2003. Area of Interest: C#, WPF, Silverlight, Human Computer Interface and Usablity, Graphics, AI

Updated on September 19, 2020

Comments

  • Souvik Basu
    Souvik Basu over 3 years

    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>