Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF MeasureOverride and ArrangeOverride

My question here is more of a theoretical one rather than functional. So what I'm looking for is an answer that can maybe be backed up with some documentation.

I find myself in the situation where I need to do some custom measurements/arrangements for a wpf control's children?

  1. Is it ok to measure the children based on other size constraints rather than the one received as a parameter.
  2. Some pseudocode of what I'm trying to achieve:

    MeasureOverride(size)
     {
       foreach(child in children)
       { 
         if(condition)
         {
           child.measure(size)
         }
         else
         { 
           child.measure(customSize)
           if(...)
           {
             ...
           }
           ...
         }
       }
     }
    

Should all the logic for this live inside MeasureOverride or should I just call measure with the size received as a parameter on all children and then do the logic inside ArrangeOverride? Thanks!

like image 839
user1422535 Avatar asked Jul 02 '14 09:07

user1422535


2 Answers

I think you can use any size. The argument to the MeasureOverride method specifies the size available for the control. the control can than return whatever DesiredSize it needs, even if it's bigger than the AvailableSize.

Child controls will do the same. the result of calling Measure on a child is that that child's DesiredSize is set. Again this can be anything, depending on the child's measuring logic. In your MeasureOverride method you can use your logic to make sense of the returned DesiredSizes.

If you have measurement logic it should definitely live in the MeasureOverride method (or helper methods) and not in ArrangeOverride. ArrangeOverride is for positioning only.

i'm sure you already checked this but i'll still post the link. http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.measureoverride%28v=vs.110%29.aspx

like image 146
flo_badea Avatar answered Oct 05 '22 23:10

flo_badea


Some additional points:

  • Your pseudo code is missing that you need to return the total size used in MeasureOverride(). You need to combine the children's DesiredSize into a total size your control intends to use. You cannot return availableSize, which might be infinite.
  • When you receive infinite size in MeasureOverride(), you cannot return infinite, but 0 is ok. In that case ArrangeOverride() will receive all available size.
  • When you do your size calculations, be careful not to create negative values. This can easily happen when DesiredSize is bigger than available size. Handle it like this:

    double remainingWidth = Math.Min(0, availabeSize.Width - DesiredSize.Width);

  • You probably need to repeat the logic form MeasureOverride() in ArrangeOverride(). Careful when using values calculated in MeasureOverride() within ArrangeOverride(), because the available size is often different.

  • Ensure that you call Measure() and Arrange() for every child. If you don't, you will not get any error message, but the Framework will call them with probably wrong size parameters.
like image 26
Peter Huber Avatar answered Oct 05 '22 23:10

Peter Huber