I am surprised that no one suggested using the actual FlowDocument to lay out your interface.
I used FlowDocument before to achieve complex arrangements. It works quite well, except that some inheritance of properties is blocked (e.g. t21>). This is not hard to get around.
In your case, just put # 2 in a separate UserControl for each section and inside your FlowDocument use InlineUIContainer to wrap each section.
<Window> <DockPanel> ... toolbars, etc ... <FlowDocumentScrollViewer ...> <FlowDocument> ... <InlineUIContainer> <my:PartialNumberTwo DataContext="{Binding ...}" /> </InlineUIContainer> ...
Of course, there are restrictions that FlowDocument can fulfill, so it may not work for your scenario.
An extremely flexible option is to create a custom panel that sets out its children in the WrapPanel style, but does this by fitting rectangles, and prior to launching it selects any area covered by our own siblings as inaccessible.
Such a panel will be used as follows:
<Grid ...> ... RowDefinitions, ColumnDefinitions ... <panels:WrapIntoRemainingSpacePanel RowSpan="4" ColumnSpan="3"> <my:Control2Part1 /> <my:Control2Part2 /> <my:Control2Part3 /> <my:Control2Part4 /> </panels:WrapIntoRemainingSpacePanel> <my:Control1 Grid.Row="0" Grid.ColumnSpan="3" /> <my:Control3 Grid.Row="2" Grid.Column="2" Grid.ColumnSpan="2" /> <my:Control4 Grid.Row="3" Grid.RowSpan="2" />
This panel will be implemented as follows:
- In ArrangeOverride, schedule a Dispatcher.BeginInvoke callback to do the actual placement and report the full size used
- In the callback, get the rectangles representing all the bounding fields of my siblings in my parent coordinate space.
- Sort Y coordinates (top and bottom) of all placed rectangles
- Place each child by finding the first Y coordinate in a sorted list that has space for somewhere for content somewhere and place it as far as possible on the left
- VisualTransform Monitor siblings for changes if any call to InvalidateArrange ()
Ray burns
source share