views:

62

answers:

1

How would I bind to a collection of shapes?

I'd like to build a small application (just for learning purposes) where I utilize MVVM for drawing shapes.

The DataContext of the MainWindow is the MainWindowViewModel

That MainWindowViewModel has an ObservableCollection of shapes.

I have currently only a Canvas on my MainWindow with its DataContext bound to that collection which does not work:

<Window x:Class="DesktopCanvas.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
>
    <Canvas DataContext="{Binding Source=ShapeCollection}">
    </Canvas>
</Window>

In the constructor of the MainWindowViewModel I add a rectangle like this:

this.ShapeCollection = new ObservableCollection<Shape>();
Rectangle rect = new Rectangle();
//Größe
rect.Height = 75;
rect.Width = 75;
//Transparenz
rect.Opacity = 100;
//Farbe
SolidColorBrush myBrush = new SolidColorBrush(Colors.Red);
rect.Fill = myBrush;
this.ShapeCollection.Add(rect);

No Binding errors so far. Any ideas?

A: 

You want to use an ItemsControl to bind to a collection of data and have each piece of data represented by some kind of UI. Also, you're not setting the binding correctly. Let's start with how these two things might look:

<ItemsControl ItemsSource="{Binding Path=ShapeCollection, Element=MainWindow}">
</ItemsControl>

NOTE: the above binding declaration assumes you've applied an x:Name="MainWindow" to your Window element and that the ShapeCollection is a property off of your MainWindow class.

Now, since the default layout of an ItemsControl is a StackPanel with vertical orientation you should see your shapes stacked one on top of the other. If you wanted to change the layout of the elements you would change the ItemsControl's ItemPanelTemplate. Let's change it so the shapes are laid out horizontally and wrapped vertifcally when space runs out:

<ItemsControl Height="100" ItemsSource="{Binding ShapeCollection, ElementName=Window, Mode=Default}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

Finally let's talk about your overall approach. Right now you're actually using Shapes as your data which is actually somewhat backwards from a technique known as Mode-View-ViewModel (MVVM). In MVVM you'd just want a pure data object and then you or, better yet, your designer, define the visual representation of that data using DataTemplates. For more on MVVM I suggest just clicking on the tag here on StackOverflow and digging into the highest voted questions.

Drew Marsh