UWP has a design problem: ActualHeight/ActualWidth, which store the result of the layout operations, are always a real number. However, because they are updated so frequently, UWP does not notify when they change.
Height/Width do provide change notifications, but may often be NaN, as when the object is set to stretch to fill a parent.
It seems like the answer is: Don't. Subscribe to SizeChanged and directly adjust properties that depend on size, using ActualHeight and ActualWidth.
However, I'm encountering another problem with the latter, where not all child controls redraw correctly, and it seems to be because the SizeChanged event sometimes gets dropped, and so some child controls get stuck with an old size value. This problem gets more noticeable with rapid resizing. A slow small resize causes them to redraw correctly. I'm guessing that for performance, UWP rendering framework tries to reduce the amount of work happening while drawing.
What's the right way to do this? And/or if I continue using SizeChanged, how can I either ensure that the final values are rendered, or that the work done is reduced so that all SizeChanged events are received?
(w/ Win10 16299 SDK)
UPDATE: The misbehavior of SizeChanged was in part due to my misordering of the event handler logic. However, there are sill frames in which objects that should be positioned identically are misaligned. On further inspection, that appears to be a bug in Grid positioning.
Let's assume you have 2 elements: a TextBox and a ComboBox. You want whenever the textbox's size change, the combobox's size should be changed too. See this.
<TextBox Name="TextBox1"></TextBox>
<ComboBox Width={Binding ElementName=TextBox1, Path=Width}
Height={Binding ElementName=TextBox1, Path=Height}><ComboBox/>
If you want to bind in cs file. You can do this:
TextBox TextBox1=new TextBox();
Binding WidthBinding=new Binding();
WidthBinding.Source=ViewModelClass;
WidthBinding.Path=new PropertyPath("WidthPropertyInViewModelClass");
WidthBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
BindingOperations.SetBinding(TextBox1, TextBox.WidthProperty, WidthBinding);
For more information about binding in code file, see this, and this