I am drawing different types of paths on canvas using databinding. Canvas is in ItemsControl and I use MiltiBinding Converter.
<ItemsControl x:Name="Items" ClipToBounds="True">
<ItemsControl.ItemsSource>
<MultiBinding Converter="{StaticResource CanvasDraw}">
<Binding Path="Coords" />
<Binding Path="Holes" />
<Binding Path="MagnetAreas" />
<Binding Path="PathElements" />
<Binding Path="Image" />
</MultiBinding>
</ItemsControl.ItemsSource>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas HorizontalAlignment="Center" VerticalAlignment="Center" Width="0" Height="0"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Resources>
<DataTemplate x:Key="img">
<Image Source="{Binding Image}" Width="200" Height="100"/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:Coord}">
<Path Data="{Binding Geometry}" Style="{StaticResource Coord}" />
</DataTemplate>
<DataTemplate DataType="{x:Type local:Hole}">
<Path Data="{Binding Geometry}" Style="{StaticResource Hole}" />
</DataTemplate>
<DataTemplate DataType="{x:Type local:MagnetArea}">
<Path Data="{Binding Geometry}" Style="{StaticResource MagnetArea}" />
</DataTemplate>
<DataTemplate DataType="{x:Type local:PathElement}">
<Path Data="{Binding Geometry}" Style="{StaticResource PathElement}" />
</DataTemplate>
</ItemsControl.Resources>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding Path=PosX}" />
<Setter Property="Canvas.Top" Value="{Binding Path=PosY}" />
<Setter Property="Panel.ZIndex" Value="{Binding Path=ZIndex}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
My ViewModel consists of 4 ObservableCollections of different types (Coords, Holes, MagnetAreas, PathElements), each derived from the same class (Element), so in converter, I just create combined collection of type Element. Every element has its own property Geometry, that is bound to DataTemplates' Path Data.
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
ObservableCollection<Element> combinedCollection = new();
if (values == null || values.Length <= 0)
return combinedCollection;
foreach (var element in (ObservableCollection<Coord>)values[0])
combinedCollection.Add(element);
foreach (var element in (ObservableCollection<Hole>)values[1])
combinedCollection.Add(element);
foreach (var element in (ObservableCollection<MagnetArea>)values[2])
combinedCollection.Add(element);
foreach (var element in (ObservableCollection<PathElement>)values[3])
combinedCollection.Add(element);
return combinedCollection;
}
Until now, everything works perfectly. But I would like to draw also one image on the canvas. I guess I have to do that through DataTemplate as well (manually adding Image element into canvas did not work), but I have no idea how to change my Converter and binding Paths to do that, since this DataTemplate has different type. Property ImageSource Image is also in my ViewModel. Code above obviously does not work, but at least, converter is correctly triggered when property Image is changed.