I'm trying to create a View in WPF and having a hard time figuring out how to set it up. Here's what I'm trying to build:
So it seems complicated to me. It seems that each item on the timeline has to render its own segment of the line. That's fine. But the distance between the top of the item to the line (and the bottom of the item to the line) could vary. If one item has the line 50 px down from the top and the next item has the line 100 px down from the top, then the first item needs 50 px of padding so that the line segments add up.
I think I could solve that problem, however, we only need to add padding if these two items are on the same line in the WrapPanel! Let's say there are 5 items and only room on the screen for 3 across... the WrapPanel will put the other two on the next line. That's ok, but that means only the first 3 need to pad together, and the last 2 need to pad together.
This is what's giving me a headache. Is there another approach I could look at?
EDIT: I'm leaning towards replacing the WrapPanel with a custom panel that inherits from Canvas and overrides the MeasureOverride and ArrangeOverride methods.
The ideal solution to this would probably be using Adorners. On the AdornerLayer you would have a custom Adorner for each item on the Panel (you define it in the DataTemplate). You will be able to retreive dimensions an positions of each item (Boundingbox of the Adorner). Also on the AdornerLayer you would then draw the lines between these boundingboxes. Using this solution you can layout your items any way you want (using any Panel you want) and the items will still be connected with lines.
A long time ago I used this approach for a graph visualizer. The nodes where arbitary UIElements that could be layouted in any way. The items where connected with lines.
To make all items align perfectly you could use a Canvas as the root Panel in you ItemTemplate. The Canvas can be 0x0 units big. You would then arrange your elements around that Canvas. The Canvas becomes your point of reference. Everything on top of the line will get negative Canvas.Top values. Another approach would be to use negative margins that are bound to the height of the top and bottom controls that surrond the line. Use a IValueConverter (Height*-1) to invert the Height.