Search code examples
silverlightlayoutrendertransform

View doesn't expand to fit a scaled Border


I have a Border inside a Grid which is displayed in a ChildWindow. I need to make the Border larger so I applied a RenderTransform to it. However the ChildWindow hasn't expanded to fit the scaled Border. It looks like the size is being calculated before the render transform is applied. This means that the border is now cropped and I can only see a 1/4 of it.

I've tried wrapping the Border in a ScrollViewer and a ViewBox, neither of which have worked.

<Grid>
    ...
    <Border x:Name="Border"
            Grid.Row="3"
            Grid.ColumnSpan="2"
            Background="White"
            BorderBrush="Black"
            BorderThickness="1"
            CornerRadius="5"
            VerticalAlignment="Top"
            Height="{Binding NewLabelTemplate.Height}"
            Width="{Binding NewLabelTemplate.Width}">
        <Border.RenderTransform>
            <ScaleTransform CenterX="0.5"
                            CenterY="0.5"
                            ScaleX="2"
                            ScaleY="2"/>
        </Border.RenderTransform>
        ...
    </Border>
    ...
</Grid>

How can I get the ChildWindow to use the ultimate size of the border when calculating its size?

I can't apply either the scale to the ChildWindow or use the rendered height and width of the Border directly as there are other elements in the Grid that I don't want to be scaled.


Solution

  • At the moment I can think of two possible solutions:

    1. Calculate Scaled Properties for Your Border to Bind to

    <Grid>
        <Grid.Resources>
            <ScaledSizeProperties x:Key="BorderSizes"
                ScaleFactor="2"
                BorderThickness="1"
                CornerRadius="5"
                Height="{Binding NewLabelTemplate.Height}"
                Width="{Binding NewLabelTemplate.Width}"/>
        </Grid.Resources>
        ...
        <Border x:Name="Border"
            Grid.Row="3"
            Grid.ColumnSpan="2"
            Background="White"
            BorderBrush="Black"
            VerticalAlignment="Top"
            BorderThickness="{Binding
                Path=ScaledBorderThickness, Source={StaticResource BorderSizes}}"
            CornerRadius="{Binding
                Path=ScaledCornerRadius, Source={StaticResource BorderSizes}}"
            Height="{Binding
                Path=ScaledHeight, Source={StaticResource BorderSizes}}"
            Width="{Binding
                Path=ScaledWidth, Source={StaticResource BorderSizes}}">
            ...
        </Border>
        ...
    </Grid>
    

    and code:

    public class ScaledSizeProperties : DependencyObject
    {
        //add input DependencyProperties for:
        //double ScaleFactor
        //double BorderThickness
        //double CornerRadius
        //double Height
        //double Width
    
        //add output DependencyProperties for:
        //double ScaledBorderThickness
        //double ScaledCornerRadius
        //double ScaledHeight
        //double ScaledWidth
    
        public double ScaleFactor
        {
            get { return (double) GetValue( ScaleFactorProperty ); }
            set { SetValue( ScaleFactorProperty, value ); }
        }
    
        public static readonly DependencyProperty ScaleFactorProperty =
            DependencyProperty.Register( "ScaleFactor", typeof( double ),
            typeof( ScaledSizeProperties ),
            new PropertyMetadata( 1, OnScaleFactorChanged ) );
    
        private static void OnScaleFactorChanged(DependencyObject d,
            DependencyPropertyChangedEventArgs e)
        {
            //recalculate all size properties
        }
    
        public double Height
        {
            get ...
            set ...
        }
    
        ... DependencyProperty HeightProperty ... OnHeightChanged ...
    
        private static void OnHeightChanged(DependencyObject d,
            DependencyPropertyChangedEventArgs e)
        {
            //recalculate ScaledHeight
        }
    }
    

    2. Use a LayoutTransformer instead of RenderTransform

    The LayoutTransformer that is part of the Toolkit is now (since SL5) official part of the base library package of Silverlight.

    <Grid>
    ...
    <LayoutTransformer
        Grid.Row="3"
        Grid.ColumnSpan="2"
        VerticalAlignment="Top">
        <LayoutTransformer.LayoutTransform>
            <ScaleTransform CenterX="0.5"
                            CenterY="0.5"
                            ScaleX="2"
                            ScaleY="2"/>
        </LayoutTransformer.LayoutTransform>
        <Border x:Name="Border"
            Background="White"
            BorderBrush="Black"
            BorderThickness="1"
            CornerRadius="5"
            Height="{Binding NewLabelTemplate.Height}"
            Width="{Binding NewLabelTemplate.Width}">
            ...
        </Border>
    </LayoutTransformer>
    ...
    </Grid>