Reputation: 490
So it seems either I don't understand scaling in WPF or all solutions are overly complicated. The background is, I have to scale a parent UserControl and its children, and at the same time trying to avoid the too-smart-for-me XAML. So I'm trying to go with a different (easier?) approach to scaling in WPF.
First, I subscribe to the SizeChanged event. From the new and previous size (both provided from the event parameters) I calculate the ratios for width and height, and apply them to each child element, thus resizing them. Sounds simple. However, when the UserControl is actually generated, the SizeChanged event is fired for the first time. At this point the "old" height and width are both 0 (or NaN, respectively).
Here is how I do it at the moment (simplified; ignoring the problem with NaN):
private void ScaleElement(FrameworkElement element,
double previousWidth, double previousHeight,
double newWidth, double newHeight)
{
double scalingFactorX;
double scalingFactorY;
scalingFactorX = newWidth / previousWidth;
scalingFactorY = newHeight / previousHeight;
double elementRelativePosX = element.Margin.Left / previousWidth;
double elementRelativePosY = element.Margin.Top / previousHeight;
element.Margin = new Thickness(newWidth * elementRelativePosX, newHeight * elementRelativePosY, 0, 0);
element.Width *= scalingFactorX;
element.Height *= scalingFactorY;
}
I'd like to handle this first fired event by changing the non-existant "old" size with the size of the UserControl as it was intended at design time. I could be wrong, but XAML hints at a static property called DesignProperties.DesignWidth (XAML: e.g. d:DesignWidth="300"). Can I somehow access this? If not, is there an alternative approach to solving the problem (or scaling in general) programatically? Thanks in advance.
Upvotes: 0
Views: 538
Reputation: 4481
If you only want to resize your content proportionally, you may want to give the ViewBox a try: http://wpftutorial.net/ViewBox.html
Upvotes: 1
Reputation: 4481
If I understand you right, you want to determine suitable sizes and positions for multiple items within some usercontrol (container) whenever the available space changes. Usually this is done by just choosing an appropriate layout panel, i.e. StackPanel, WrapPanel, DockPanel, Grid, Canvas...
If no standard implementation satisfies your needs, you can create your own layout panel by implementing the functions 'ArrangeOverride' and 'MeasureOverride' (Tutorial here). Then your UserControl can use this layout panel. WPF tends to stimulate using "composite controls", i.e. you should rather use your CustomPanel in the ControlTemplate or Xaml (no fear, it wants to be your friend) of your UserControl, in contrast to deriving the UserControl from the CustomPanel.
Upvotes: 1
Reputation: 2479
The d:DesignWidth/Height properties are for design time use only, and are not accessible at run time.
I'm not sure of the best approach to your question, but you might find the ActualWidth/ActualHeight properties useful. Or you may well not need to use scaling at all through use of appropriate containers and sizing (e.g. * sized Grid cells, DockPanel.LastChildFill = true, etc) - WPF can do a lot of that for you. The explicit scaling is more for things like bitmap images or temporary size changes.
Upvotes: 1