Reputation: 394
I have a WPF control docked into a WPF host control in a WinForms app. The WPF control is set to stretch both horizontally and vertically, and the host control is docked in an anchored group box.
My WPF control has a Canvas that fills its space that i use to place children which are a custom class that is derived from Canvas.
I subscribed to the main Canvas' SizeChanged event and applied a scale transform so that the canvas and its children would shrink and grow in a zoom like fashion when the control is resized, which is working, but for some reason the parent canvas is shrinking at a much higher rate than the children, making the children fall off of the canvas at a certain point because of the scale rate.
This is my code:
private void EditorCanvas_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (e.PreviousSize.Width == 0)
return;
double YDiff = e.PreviousSize.Height / e.NewSize.Height;
double XDiff = e.PreviousSize.Width / e.NewSize.Width;
Scale.ScaleY /= YDiff;
Scale.ScaleX /= XDiff;
}
The children of the canvas seem to be scaling at the correct rate, and the canvas seems to be scaling at a much higher rate.
Does anyone see any reason / know any reason why this may be happening?
Pictures of behavior... Notice the white space behind the smaller panels
Before
Scaled
Upvotes: 1
Views: 2491
Reputation: 44038
This:
I subscribed to the main Canvas' SizeChanged event and applied a scale transform so that the canvas and its children would shrink and grow in a zoom like fashion when the control is resized, which is working, but for some reason the parent canvas is shrinking at a much higher rate than the children, making the children fall off of the canvas at a certain point because of the scale rate.
is what a Viewbox
does. Put a Viewbox
as the root element in the WPF visual tree. and set its Stretch
property to whatever suits your needs. and remove all that size calculations. WPF doesn't need size calculations.
Upvotes: 5
Reputation: 55720
It looks like you are missing some intermediate steps (i.e. some size changes). If your application can't process the size change events fast enough Windows might be skipping some in the middle in order to catch up.
For instance, let's say your app starts with a height of 1000. Then quickly changes to 100, but in the process it goes through a number of intermediate sizes (500, 250, 125). If you miss one or two of those you would end up with something like this in your ScaleY calculation:
0. Height = 1000; ScaleY = 1
1. Height: 1000 > 500; ScaleY = 1/(1000/500) = 0.5
2. [misses 250]; no scaleY adjustment
3. Height: 250 > 125; ScaleY = 0.5 / (250/125) = 0.25 // when it should actually be .125
4. Height: 125 > 100; ScaleY = 0.25 / (125/100) = 0.2 // when it should actually be 0.1
You should instead store and use the original size and compute absolute values instead of continuously differentials..
Upvotes: 1