Search code examples
xamluser-interfaceuwpuwp-xamlstackpanel

Change stackpanel's items height a and width based on window size


I want to make a simple UI that contains 3 areas, and I want them as shown in the picture, using about 33% of the Window height each one:

I was able to do this width a Grid and his RowDefinitions but the problema is that I want these three areas to change orientation based on window width, so I thought that using a StackPanel instead of a Grid and changing his "Orientation" property to "Horizontal" when the window is bigger could be the solution. But now I'm facing other problem, I don't know hot to set heights or widths for each area that that change automatically because I can't use "0.3*" for each like in the Grid.RowDefinitions.

Any idea on how to implement this UI?

Thanks!

EDIT: Okay based on a comment here is my actual code:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup>
            <VisualState>
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="500"/>
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    // Changes on orientation
                </VisualState.Setters>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
    <Grid.RowDefinitions>
        <RowDefinition Height="0.35*"/>
        <RowDefinition Height="0.30*"/>
        <RowDefinition Height="0.35*"/>
    </Grid.RowDefinitions>
    <Grid Grid.Row="0" Background="Green">

    </Grid>
    <Grid Grid.Row="1">

    </Grid>
    <Grid Grid.Row="2" Background="Blue">

    </Grid>
</Grid>

Solution

  • Here's XAML:

    <Grid SizeChanged="Stack_OnSizeChanged">
        <StackPanel Orientation="{x:Bind Orientation, Mode=OneWay}">
            <Rectangle Height="{x:Bind PercentHeight, Mode=OneWay}" Width="{x:Bind PercentWidth, Mode=OneWay}" Fill="Lime"/>
            <Rectangle Height="{x:Bind PercentHeight, Mode=OneWay}" Width="{x:Bind PercentWidth, Mode=OneWay}" Fill="DeepPink"/>
            <Rectangle Height="{x:Bind PercentHeight, Mode=OneWay}" Width="{x:Bind PercentWidth, Mode=OneWay}" Fill="DeepSkyBlue"/>
        </StackPanel>
    </Grid>
    

    Here's code behind:

            public static readonly DependencyProperty PercentHeightProperty = DependencyProperty.Register(
                "PercentHeight", typeof(double), typeof(MyUserControl1), new PropertyMetadata(default(double)));
    
            public double PercentHeight
            {
                get => (double) GetValue(PercentHeightProperty);
                set => SetValue(PercentHeightProperty, value);
            }
    
            public static readonly DependencyProperty PercentWidthProperty = DependencyProperty.Register(
                "PercentWidth", typeof(double), typeof(MyUserControl1), new PropertyMetadata(default(double)));
    
            public double PercentWidth
            {
                get => (double) GetValue(PercentWidthProperty);
                set => SetValue(PercentWidthProperty, value);
            }
    
            public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register(
                "Orientation", typeof(Orientation), typeof(MyUserControl1), new PropertyMetadata(default(Orientation)));
    
            public Orientation Orientation
            {
                get => (Orientation) GetValue(OrientationProperty);
                set => SetValue(OrientationProperty, value);
            }
    
            private int _count = 3;
    
            public MyUserControl1()
            {
                InitializeComponent();
            }
    
            private void Stack_OnSizeChanged(object sender, SizeChangedEventArgs e)
            {
                Orientation = e.NewSize.Width > 512 ? Orientation.Horizontal : Orientation.Vertical;
    
                if (Orientation == Orientation.Horizontal)
                {
                    PercentHeight = e.NewSize.Height;
                    PercentWidth = e.NewSize.Width / _count;
                }
                else
                {
                    PercentHeight = e.NewSize.Height / _count;
                    PercentWidth = e.NewSize.Width;
                }
            }
    

    Enjoy resizing your window.