0

I need to display a collection of RectangleGeometry rectangles that would be added and removed in a ViewModel so I created an ObservableCollection of RectangleGeometry objects and bind to them inside a GeometryGroup.

To make my problem really simple to see, I created a very simple project without the MVVM. Even if I bind to the simple code-behind, the rectangles do not appear. I'm still in WPF learning mode, so if you have a better way of doing this using templates or something else, I'm very open.

The xaml:

<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:local="clr-namespace:WpfApplication1"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        Title="MainWindow"
        Width="1024"
        Height="768"
        mc:Ignorable="d">
   <Grid>
      <Canvas>
         <Path Fill="Red" Opacity=".4">
            <Path.Data>
               <GeometryGroup Children="{Binding Rectangles}"
                              FillRule="NonZero" />
            </Path.Data>
         </Path>
      </Canvas>
   </Grid>
</Window>

Code-behind:

Imports System.Collections.ObjectModel

Class MainWindow

   Public Sub New()
      InitializeComponent()
      Rectangles = New ObservableCollection(Of RectangleGeometry)
      Rectangles.Add(New RectangleGeometry(New Rect(50, 50, 500, 100)))
      Rectangles.Add(New RectangleGeometry(New Rect(50, 50, 100, 500)))
      Rectangles.Add(New RectangleGeometry(New Rect(200, 200, 100, 100)))
      Rectangles.Add(New RectangleGeometry(New Rect(400, 400, 100, 100)))
      Rectangles.Add(New RectangleGeometry(New Rect(20, 20, 100, 100)))
   End Sub

   Public Property Rectangles As ObservableCollection(Of RectangleGeometry)

End Class
IWishUWell
  • 23
  • 4
  • Take a look at [this post](http://stackoverflow.com/a/22325266/1136211). You may replace the Rectangle in the ItemTemplate with a Path that has a RectangleGeometry in its Data property. You could then also avoid the ItemContainerStyle, as you wouldn't have to bind Canvas.Left and Canvas.Top properties. – Clemens Apr 20 '16 at 07:43
  • Thank you. I'm investigating it now. – IWishUWell Apr 21 '16 at 22:33

1 Answers1

0

You're going about this completely the wrong way. On one hand you're trying to construct GUI objects (i.e. RectangeGeometry) directly and then on the other you're trying to use data binding. Pick one.

If you do decide to use DataBinding then create a data structure for your rectangle objects and bind to an ObservableCollection of those instead. And don't use a Canvas, use a an ItemsControl with its ItemPanel set to Canvas. Override the ItemTemplate for the items you wish to draw using DataTemplate and then set the Canvas.Left/Canvas.Top parameters in the ItemContainerStyle.

Mark Feldman
  • 15,731
  • 3
  • 31
  • 58
  • Thank you. I'll research how that is done and get back to you. I didn't do a good job of explaining why I need to do what I'm doing. I need to draw rectangles over an image with .4 opacity, but I can't have them become more opaque when they overlap. That is why I'm choosing RectangleGeometry. If I drag a UIElement instead it would be much easier, but then for overlaps the opacity increases. – IWishUWell Apr 21 '16 at 22:32