Reputation: 51
I need to add geometry objects to a canvas through code.. Meaning when you click a button a shape is added. I sent the canvas as a parameter to the function and then use canvas.children.add() but that kind of screws the whole mvvm idea, doesn't it? Is there a better way to do it?
Upvotes: 2
Views: 3587
Reputation: 6289
You can use ItemsControl
with Canvas
as it's items panel. Then in VM you need a collection to hold all the items. Each item should have all the properties for placement.
So, in code, it will look like this (I'm omitting change notification for brevity):
The item:
public class CanvasShape : INotifyPropertyChanged
{
public double Top {get; set;}//TODO: add change notification
public double Left {get; set;}//TODO: add change notification
public Geometry PathData {get; set;}//TODO: add change notification
}
In the VM:
public ObservableCollection<CanvasShape> Shapes {get; set;}
.....
//Add some logic to fill the collection
In XAML:
<!--The DataContext here is the VM-->
<ItemsControl ItemsSource="{Binding Shapes}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas IsItemsHost="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<!--These setters will control the position of the shape; the DataContext here is CanvasShape-->
<Setter Property="Cavas.Top" Value="{Binding Top}"/>
<Setter Property="Cavas.Left" Value="{Binding Left}"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Path Data="{Binding PathData}"
.......
/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Upvotes: 5
Reputation: 16230
No, there's no better way to do it.
If you define shapes in XAML, they get Add()'ed to the Canvas.Children just the same way.
Now, if you want to do that in a clean Mvvm way, you probably have to get inventive with your viewmodel. I'd add a VM ICommand for the button (so you can connect ot it), in the handler, I'd add some kind of object to an ObservableCollection, and then do something in your view to create the shapes from that ViewModel Collection (in xaml or codebehind)
Upvotes: -1