Я бы сделал BaseClass
для всех виджетов, а затем построил бы ViewModel
, который наследуется от этого BaseClass
для каждого виджета, вместе с View
, чтобы идти с этим ViewModel
После этого у меня будет что-то вроде ObservableCollection<WidgetBaseViewModel> OpenWidgets
в основном приложении ViewModel
, и я привяжу его к ItemsControl
.
ItemsControl
будет иметь ItemsPanelTemplate
, установленный в Canvas
, и каждый WidgetBaseViewModel
будет содержать свойства Top
, Left
, Height
и Width
.
Фактический пользовательский интерфейс для отображения каждого виджета будет основан на DataTemplate
и может быть чем угодно, хотя UserControl
будет проще
<ItemsControl ItemsSource="{Binding OpenWidgets}">
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type local:WidgetAViewModel}">
<local:WidgetAView />
</DataTemplate>
<DataTemplate DataType="{x:Type local:WidgetBViewModel}">
<local:WidgetBView />
</DataTemplate>
</ItemsControl.Resources>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Canvas ... />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Кроме того, вы 'Вам нужно будет привязать ваш Canvas.Top
/ Canvas.Left
к ItemContainerStyle
вместо фактического ItemTemplate
, чтобы он правильно отображался на холсте.