none
Question ​about WPF, ​Measure​Override and ​Arrange​Override

    Question

  • I'm much more familiar with WinForms than WPF but I am learning...

    I have a situation where I have a UserControl that needs to lay out child controls at runtime in a way that isn't supported by any of the currently supplied containers (StackPanel, Grid, etc). So in my derived UserControl, I override MeasureOverride and ArrangeOverride.

    But for both of these, on each child you are supposed to call Measure (when overriding MeasureOverride) or Arrange (when overriding ArrangeOverride).

    OK fine, except there are additional controls inbetween the derived UserControl and where the child controls actually reside. There is a Border and a Grid control inbetween the derived UserControl and the child controls. Am I supposed to call Measure and Arrange on the child controls even though they are two levels deeper, or should I also derive a new class from Grid that contains the actual child controls.

    Maybe I'm just not "getting" a lot of the WPF concepts yet but everything seems way more complicated than it needs to be. Now suddenly we have Width, RenderWidth, ActualWidth, a logical tree, a visual tree, etc.

    Currently the problem I'm running into is that the derived UserControl can be enlarged based on the child sizes and positions, but it never shrinks again. All container controls in the hierarchy have height set the Auto.

    Friday, March 11, 2011 5:48 PM

Answers

  • By your description, you should be implementing a class deriving from Panel instead of UserControl. The rendering in WPF is pretty much straight forward.

    Measure:

    A control is given an available size by its parent (which is the WPF hosting process in the case of the top of the visual tree element) and is asked to measure itself aquiring its desired size. The control does the same to each of its visual children. At the end of this process the control and its visual children have aquired their desired size and the control, doing its maths, returns to its parent the size it wants to render itself.

    Arrange:

    A control is given a finalSize and, doing its maths, gives its children rectangles for them to render themselves in and, in the end, returns the actual size that was used.

     

    Having said that, any time some UIElement in the visual tree changes its size the process is repeated. If you say how you want your items to be displayed I can provide an initial approach for you to work with.


    Bigsby, Lisboa, Portugal
    O que for, quando for, é que será o que é...
    Wenn ist das Nunstruck git und Slotermeyer? Ja! ... Beiherhund das Oder die Flipperwaldt gersput!
    http://bigsby.eu
    Friday, March 11, 2011 6:23 PM
  • Unless there's something *really* custom about your layout, you should only call Measure and Arrange on your immediate children.  These Elements, in turn, will call Measure on their children, so it should all work out in the end.  That is, if you Measure the Border, it will Measure its Child in turn, and will use those results to return measurement info to your custom conainer.

    I also agree with Bigsby, you probably want to derive from Panel and have the Border, etc, as children of your Panel.

    -Adam Smith [MSFT]


    -Adam Smith [MS]
    Saturday, March 12, 2011 1:14 AM
    Moderator

All replies

  • By your description, you should be implementing a class deriving from Panel instead of UserControl. The rendering in WPF is pretty much straight forward.

    Measure:

    A control is given an available size by its parent (which is the WPF hosting process in the case of the top of the visual tree element) and is asked to measure itself aquiring its desired size. The control does the same to each of its visual children. At the end of this process the control and its visual children have aquired their desired size and the control, doing its maths, returns to its parent the size it wants to render itself.

    Arrange:

    A control is given a finalSize and, doing its maths, gives its children rectangles for them to render themselves in and, in the end, returns the actual size that was used.

     

    Having said that, any time some UIElement in the visual tree changes its size the process is repeated. If you say how you want your items to be displayed I can provide an initial approach for you to work with.


    Bigsby, Lisboa, Portugal
    O que for, quando for, é que será o que é...
    Wenn ist das Nunstruck git und Slotermeyer? Ja! ... Beiherhund das Oder die Flipperwaldt gersput!
    http://bigsby.eu
    Friday, March 11, 2011 6:23 PM
  • OK so are you saying I should not use UserControl at all, and instead derive from Panel (as my "root" control)? Or should I derive from Panel and use that as the container (above the Border control, replacing the Grid in my example), that will host the actual child controls?

    Anyway, I believe I found a bug in my code that was preventing the root control from shrinking properly. It now resizes properly. While this now works, it still feels as if I am not doing the right thing since I'm bypassing the Border and Grid controls' MeasureOverride and ArrangeOverride methods.

    Friday, March 11, 2011 6:37 PM
  • Unless there's something *really* custom about your layout, you should only call Measure and Arrange on your immediate children.  These Elements, in turn, will call Measure on their children, so it should all work out in the end.  That is, if you Measure the Border, it will Measure its Child in turn, and will use those results to return measurement info to your custom conainer.

    I also agree with Bigsby, you probably want to derive from Panel and have the Border, etc, as children of your Panel.

    -Adam Smith [MSFT]


    -Adam Smith [MS]
    Saturday, March 12, 2011 1:14 AM
    Moderator
  • They are right, you should probably use a panel. I once needed to create a trackbar with several bookmarks for multimedia files. I used a Panel and called the Measure and Arrange overrides for the bookmarks inside that thing. The bookmarks were custom controls that could themselves decide how they needed to look like. If that is something you need to so as well, go for the panel.
    Geert van Horrik - CatenaLogic
    Visit my blog: http://blog.catenalogic.com

    Looking for a free open-source MVVM framework for WPF and Silverlight? Check out Catel!
    Saturday, March 12, 2011 11:09 AM
  • Hi BitFlipper,

    I am marking your issue as "Answered", if you have not got what you need, please let us know.

     

    Best regards,


    Sheldon _Xiao[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, March 21, 2011 10:02 AM
    Moderator