0

The Title explains my question I guess. I have one root rectangle which has children rectangles which can also have children rectangles. What would be the best way to draw all of them dynamically on a canvas?

My Rectangle-ViewModel:

    public class SketchRectangleViewModel:ViewModelBase
    {

        public SketchRectangleViewModel(SketchRectangle sr)
        {
            _id = sr.Id;
            _x = sr.x;
            _y = sr.y;
            _height = sr.Height;
            _width = sr.Width;
            _name = sr.Name;
            _parentId = sr.ParentId;
        }

        private Guid _id;
        private int _x;
        private int _y;
        private int _height;
        private int _width;
        private Guid _parentId;
        private string _name;
        private ObservableCollection<SketchRectangleViewModel> _children = new ObservableCollection<SketchRectangleViewModel>();
        private bool _isSelected;
    }
Timothy Groote
  • 8,614
  • 26
  • 52
hullunist
  • 1,117
  • 2
  • 11
  • 31

1 Answers1

1

You could make a flat collection of all SketchRectangleViewModel objects in your view model:

How to flatten tree via LINQ?

...and bind the collection of all SketchRectangleViewModel objects to an ItemsControl:

<ItemsControl ItemsSource="{Binding YourCollection}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas Width="100" Height="100" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="ContentPresenter">
            <Setter Property="Canvas.Left" Value="{Binding X}"/>
            <Setter Property="Canvas.Top" Value="{Binding Y}"/>
        </Style>
    </ItemsControl.ItemContainerStyle>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Rectangle Width="{Binding Width}" Height="{Binding Height}" Fill="Green" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Note that you can only bind to public properties of the SketchRectangleViewModel class, so you need to turn your fields into properties:

public double X { get; set; }
mm8
  • 163,881
  • 10
  • 57
  • 88
  • 1
    Sorry I had other things to do first and was not at the Computer. Tried it and it works like a charm, thank you! Added the call to flatten my Collection whenever the Rectangles Collection gets changed or when a new Element is added. – hullunist Jun 30 '17 at 12:54