30

How can you relatively position elements in WPF? The standard model is to use layout managers for everything, but what if you want to position elements (on a Canvas, for example) simply based on the position of other elements?

For example, you may want one element (say a button) to be attached the side of another (perhaps a panel) independent of the position or layout of that panel. Anyone that's worked with engineering tools (SolidWorks, AutoCad, etc.) is familiar with this sort of relative positioning.

Forcing everything into layout managers (the different WPF Panels) does not make much sense for certain scenarios, where you don't care that elements are maintained by some parent container and you do not want the other children to be affected by a change in the layout/appearance of each other. Does WPF support this relative positioning model in any way?

animuson
  • 53,861
  • 28
  • 137
  • 147
Marchy
  • 3,334
  • 5
  • 37
  • 27
  • I'm not sure I fully understand the question. Can you give an example of a screen layout that you don't believe can be achieved with the WPF model? – 17 of 26 Oct 01 '08 at 15:30
  • I agree, the question is confusing ... it seems like a simple StackPanel would do the trick. – cplotts Oct 08 '08 at 02:30
  • 3
    I don't think it's confusing, and a StackPanel would only handle the simplest of cases. What he wants is the equivalent of RelativeLayout in Android. – user316117 Sep 25 '12 at 15:29
  • That is exactly it (Android's RelativeLayout). Seems like WPF doesn't support this layout scenario. Best workaround I've found is to wrap a Canvas around whichever UI element(s) you want to position relative to and then use Canvas.Top/Bottom/Left/Right to place the element relative to the boundaries of the canvas (and thus wrapped element). – Marchy Sep 25 '12 at 22:38

2 Answers2

15

Instead of putting (as in your example) a button directly on the canvas, you could put a stackpanel on the canvas, horizontally aligned, and put the two buttons in there.

Like so:

<Canvas>
  <StackPanel Canvas.Left="100" Canvas.Top="100" Orientation="Horizontal">
    <Button>Button 1</Button><Button>Button 2</Button>
  </StackPanel>
</Canvas>

alt text

I think that it's quite flexible when you use more than 1 layout in a form, and you can create pretty much any configuration you want.

Community
  • 1
  • 1
Dave Arkell
  • 3,920
  • 2
  • 22
  • 27
  • Combining this suggestion with the one from Jobi Joy would be a workaround I suppose: You would put a Stackpanel inside a Canvas and use TranslateTransform to adjust distance between the elements. – ArthurT Oct 16 '15 at 10:01
11

Good question. As far as I know, we need to have a different custom panel to get this feature. Since WPF is based on Visual Hierarchy there is no way to have this sort of Flat structure for the elements in the platform.

But Here is a trick to do this. Place your elements in the same position and give relative displacement by using RenderTransform.TranslateTransform. This way your TranslateTransfrom's X and Y will always be relatuve to the other element.

Jobi Joy
  • 49,102
  • 20
  • 108
  • 119
  • _"WPF is based on Visual Hierarchy there is no way"_ - this has been false since the first versions of WPF. See `Grid` for reference. – Gusdor Aug 05 '15 at 08:28
  • @Gusdor Yeah, if you use the drag-and-drop designer it will just slap everything inside the Grid (or whatever your root element is) and give them margins to keep their positioning where you put them. You could call that a flat visual structure I think. – Zack Aug 25 '15 at 14:39