Sorry, I donβt have a solution to your specific user-specific Grid problem, but I only have a suggestion on how you could make this simpler (and, I suppose, how WPF designers understand this). In fact, the Grid not a control element. This is the Panel that organizes the Controls . So, I suppose this is (one of) the reason (s) why you are having problems with your solution.
Instead, I would use an ItemsControl (e.g. ListBox ) with a Canvas as an ItemsPanel .
<ListBox ItemsSource="{Binding WorkItemsProperty}"> <ListBox.ItemsPanel> <ItemsPanelTemplate> <Canvas IsItemsHost="True"/> </ItemsPanelTemplate> </ListBox.ItemsPanel> </ListBox>
Now you define the appropriate properties in the WorkItem class (or WorkItemViewModel ) of type XPos and YPos , which will be bound to the Canvas.Left and Canvas.Top as follows:
<Style x:Key="WorkItemStyle" TargetType="{x:Type ListBoxItem}"> <Setter Property="Canvas.Left" Value="{Binding XPos, Mode=TwoWay}"/> <Setter Property="Canvas.Top" Value="{Binding YPos, Mode=TwoWay}"/> </Style>
You can then use this element style by setting the ItemContainerStyle ListBox property:
ItemContainerStyle="{StaticResource WorkItemStyle}"
I donβt know how to implement drag and drop because I never did it, but obviously you already did it for your custom Grid , so it should not be a big problem to use it in a ListBox . However, if you update the properties of your WorkItem , it should automatically move the item. In addition, if you add / remove an item to / from your collection ( WorkItemsProperty ), it will be automatically added / removed, since the ListBox bound to the data in the collection.
You may need to modify your WorkItemStyle depending on your scenario. For example, if the ListBox changes at runtime, you may need to make a position relative to the size of the container (Canvas). Therefore, you will need MultiBinding instead of a simple Binding . But this other story ...
Now, this is your decision whether you can move on to this approach or your Grid almost done and you do not want to change. I know this is difficult, but in my eyes the above approach is cleaner (and easier!) One!