6

I am trying to get the ActualSize of MyUserControl before it gets rendered using Measure methode of UserControl class as suggested for my previous question. However it is not working. MyUserControl has an ItemsControl that is databound with a List as shown below. The items added through uc.MyCollection = myCollection; is not getting reflected in uc.DesiredSize.Height.

MyUserControl uc= new MyUserControl();
uc.AName = "a1";
uc.Width = 194;
uc.MyCollection = myCollection; //myCollection is  a List databound to ItemsControl inside MyUserControl
uc.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
uc.Arrange(new Rect(0, 0, uc.DesiredSize.Width, uc.DesiredSize.Width)); //Needed?
uc.UCHeight = uc.DesiredSize.Height; //size of items databound to ItemsControl not reflected here
uc.UCWidth = uc.DesiredSize.Width;
uc.Margin = new Thickness(34, 42, 0, 0);
myRoot.Children.Add(uc); //myRoot is Canvas
Community
  • 1
  • 1
softwarematter
  • 28,015
  • 64
  • 169
  • 263
  • 3
    Try adding the `uc` to the root before invoking `Mesaure()` and do a `UpdateLayout()` before accessing the `DesiredSize`. Thats what I usually do. – kev Dec 29 '11 at 08:31
  • @neutrino: what is not working? The values are. 0 or are not exact? – Tigran Dec 29 '11 at 08:59
  • values are not exact. The height doesn't take into account the height dues to the items in the itemscontrol – softwarematter Dec 29 '11 at 14:02
  • Is your ListBox inside a Canvas? Canvas does not size itself based on it's Visual parent or children, and it's DesiredSize is 0 if not explicitly set. – terphi Jan 04 '12 at 18:06

3 Answers3

6

You have to override MeasureOverride and ArrangeOverride in your uc to calculate the size for your own. Inside MeasureOverride "ask" your List with "Measure" of its own size - so you can calculate the size for your own uc (returning this size in MeasureOverride) - then you get your DesiredSize after calling uc.Measure.

Stone
  • 235
  • 1
  • 3
  • 9
  • 2
    I am pretty sure you only have to implement these methods on custom panel implementations. A UC is simply a composite of other controls, so it is not necessary to implement these. – ColinE Dec 29 '11 at 16:28
  • What if the user control has an `ItemsControl` that is bound to a `List`? After creating the usercontrol, I am setting assigning the `List` property to which `ItemsControl` of `UserControl` is bound. The problem is that the `Measure` call on usercontrol returns the `DesiredSize.Height` without taking into account the Height of the `ItemsControl`. – softwarematter Dec 29 '11 at 16:54
1

Your ItemsControl binding to MyCollection will not process until your user control is in the VisualTree, so at the point you call Measure, the desiredsize is still 0.

When I need to get the size of a FrameworkElement, I set it's Opacity to 0, add it to the visual tree, and wait for the SizeChanged event.

terphi
  • 781
  • 7
  • 18
0

See https://msdn.microsoft.com/en-us/library/6xe5hazb(v=vs.110).aspx The parameter "byval e as PaintEventArgs" in the example is not needed. In order to only retrieve the size needed to show the whole string, you can create your own paintEventArgs field in the subroutine MeasureStringMin.

Evert
  • 11
  • 2