2

I'm trying to implement the example shown here [ WPF Canvas, how to add children dynamically with MVVM code behind ], but nothing is shown when I launch my program (even with IsItemHost set to True for the Canvas.

My application is made of an Entity type :

public class Entity
{
    public Entity(int x, int y, int width, int height)
    {
        X = x;
        Y = y;
        Width = width;
        Height = height;
    }

    public int X { get; set; }
    public int Y { get; set; }
    public int Width { get; set; }
    public int Height { get; set; }
}

The entities are stored in an EntitiesCollection :

public class EntitiesCollection : ObservableCollection<Entity>
{
    public EntitiesCollection()
    {
        Add(new Entity(10, 10, 10, 10));
        Add(new Entity(50, 20, 25, 25));
    }
}

Wich is a member of a a DrawingViewModel class :

public class DrawingViewModel
{
    public DrawingViewModel()
    {
        Entities = new EntitiesCollection();
    }

    public EntitiesCollection Entities;
}

The DataContext for my application is set in MainWindow.xaml.cs :

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new DrawingViewModel();
    }
}

And the MainWindow.xaml file itself looks like this :

<Window x:Class="Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Test" Height="350" Width="525" Icon="Graphics/Icons/paint.png">
    <Grid>
        <ItemsControl ItemsSource="{Binding Entities}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Canvas IsItemsHost="True"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemContainerStyle>
                <Style>
                    <Setter Property="Canvas.Left" Value="{Binding X}"/>
                    <Setter Property="Canvas.Top" Value="{Binding Y}"/>
                </Style>
            </ItemsControl.ItemContainerStyle>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Border BorderBrush="Red" BorderThickness="1" Width="{Binding Width}" Height="{Binding Height}"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</Window>

What's wrong ? Thanks.

Community
  • 1
  • 1
thomasc
  • 935
  • 9
  • 18
  • By the way, `Entity` should either provide no public setters/no setters at all and `private readonly` backing fields or implement [`INotifyPropertyChanged`](http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx). So that either the properties do not change at all or that the UI is notified of changes. – H.B. Sep 22 '12 at 15:09
  • Turning the field into a Property did not solve the issue : nothing appears when I launch the program. An I agree for the INotifyPropertyChanged, but this was just the first step :) – thomasc Sep 22 '12 at 16:18
  • So do you have any binding errors? – H.B. Sep 22 '12 at 16:32
  • I'm pretty new to binding debugging yet, but nothing is mentionned when I simply launch the program in debug mode. – thomasc Sep 22 '12 at 16:33
  • Did you read the article i linked to? You won't get any exceptions from failed bindings... – H.B. Sep 22 '12 at 16:40
  • Apparently I made something wrong when I changer the field to a property the first time, since it is now working. Sorry for that and thanks for the answer ! – thomasc Sep 22 '12 at 17:07

1 Answers1

5

Entities has to be a property instead of a field. (There should be respective binding errors.)

H.B.
  • 166,899
  • 29
  • 327
  • 400