Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6172607
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 23, 20262026-05-23T23:25:27+00:00 2026-05-23T23:25:27+00:00

In my scenario, the end user customizes his or her user interface by breaking

  • 0

In my scenario, the end user customizes his or her user interface by breaking it into rows and defining the height rule for those rows (fixed, fill space, fit content). I implement this using the WPF Grid.

The Grid starts filling the entire screen, and should not get any bigger – the user MUST be able to see the entire Grid at all times (scroll bars WITHIN rows are okay, but not scroll bars for the entire grid).

The crux of my problem: When the user creates one or more “auto” sized rows, the content in those rows can force the size of the entire grid to expand, introducing scroll bars, even when I’ve set the max height of the grid to a fixed number.

It gets worse when a star-sized row is involved, because once the grid is stretched a little, that star-sized row fills the available space, so the grid is PERMANENTLY stretched even when the auto-size row later shrinks.

I need to find a way to restrict “auto” rows so that they expand and shrink as needed, BUT the total actual height of all rows is never larger than the entire grid.

To illustrate, I have this grid with fixed max height, and rows representing all size modes.

<Grid.RowDefinitions>
    <RowDefinition Height="Auto"/>
    <RowDefinition Height="Auto"/>
    <RowDefinition Height="200"/>
    <RowDefinition Height="*"/>
</Grid.RowDefinitions>

<ScrollViewer VerticalScrollBarVisibility="Auto">
    <TextBlock>
        abc<LineBreak/>
        abc<LineBreak/>
        abc<LineBreak/>
        abc<LineBreak/>
        abc<LineBreak/>                    
    </TextBlock>
</ScrollViewer>

In this example, as the “abc” text block expands, the total height of the grid stretches beyond the fixed “300” maximum height. How can I prevent this behavior to guarantee the maximum height of the grid, while keeping the flexibility of the auto-size rows?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-23T23:25:27+00:00Added an answer on May 23, 2026 at 11:25 pm

    Okay, I discovered that I had to subclass Grid so that I could override Measure() and Arrange() layout steps.

    I don’t claim that this is a great general purpose solution, but it works for my scenario. Note especially that I’m not dealing with columns, since in my case, there’s only one column. I’m also not positioning elements within the cells (I’m leaving them anchored at top-left).

    If you need a more general solution, I think this is a very good start. The column problem is the same as the row problem, just in the other direction.

    class NoStretchGrid:Grid
    {
        //this override determines what size we ask to be
        //gotta make sure we never ask for more than the max height
        protected override System.Windows.Size MeasureOverride(System.Windows.Size constraint)
        {
            //what would a basic Grid do?
            System.Windows.Size desiredSize = base.MeasureOverride(constraint);
    
            if (desiredSize.Height > constraint.Height)
                desiredSize.Height = constraint.Height;
    
            //if max height is defined and desired height is too big, reduce it
            if (this.MaxHeight != double.NaN && desiredSize.Height > this.MaxHeight)
            {
                desiredSize.Height = this.MaxHeight;
            }
    
            return desiredSize;
        }
    
        //this override tells child controls how big they can be and where they're positioned
        protected override System.Windows.Size ArrangeOverride(System.Windows.Size arrangeSize)
        {
            //must decide how tall each row will be
            double[] desiredHeights = new double[this.RowDefinitions.Count];
            double[] minimumHeights = new double[this.RowDefinitions.Count];
            double[] finalHeights = new double[this.RowDefinitions.Count];
    
            //first, find out how tall each row wants to be
    
            //check for fixed-size rows
            for (int i = 0; i < desiredHeights.Length; i++)
            {
                if (this.RowDefinitions[i].Height.IsAbsolute)
                {
                    desiredHeights[i] = this.RowDefinitions[i].Height.Value;
                }
                else
                {
                    desiredHeights[i] = 0;
                }
    
                minimumHeights[i] = this.RowDefinitions[i].MinHeight;
            }
    
            //then ask children how big they want to be
            foreach (UIElement child in this.InternalChildren)
            {
                int row = Grid.GetRow(child);
                if (!this.RowDefinitions[row].Height.IsAbsolute && child.DesiredSize.Height > desiredHeights[row])
                {
                    desiredHeights[row] = child.DesiredSize.Height;
                }
    
                if ((child as FrameworkElement).MinHeight > minimumHeights[row])
                {
                    minimumHeights[row] = (child as FrameworkElement).MinHeight;
                }
            }
    
            double availableHeight = arrangeSize.Height;
    
            //reserve minimum heights
            for (int i = 0; i < minimumHeights.Length; i++)
            {
                finalHeights[i] = minimumHeights[i];
                availableHeight -= finalHeights[i];
            }            
    
            //allow fixed-height rows their height - if some ignoramus made fixed-heights too big, we can't help him
            for (int i = 0; i < desiredHeights.Length; i++)
            {
                if (this.RowDefinitions[i].Height.IsAbsolute)
                {
                    finalHeights[i] = this.RowDefinitions[i].Height.Value;
                    availableHeight = availableHeight + minimumHeights[i] - finalHeights[i];
                }
            }
    
            //allow auto-size rows their desired heights, so long as there's height left to be had
            for (int i = 0; i < desiredHeights.Length; i++)
            {                
                if (this.RowDefinitions[i].Height.IsAuto)
                {
                    double desiredHeightIncrease = desiredHeights[i] - minimumHeights[i];
    
                    if (desiredHeightIncrease <= availableHeight)
                    {
                        finalHeights[i] += desiredHeightIncrease;
                        availableHeight -= desiredHeightIncrease;
                    }
                    else
                    {
                        finalHeights[i] = minimumHeights[i] + availableHeight;
                        availableHeight = 0;
                    }
                }
            }
    
            //now that auto-size rows have been prevented from getting out of control, make the min heights of any star-size rows available again
            for (int i = 0; i < desiredHeights.Length; i++)
            {
                if (this.RowDefinitions[i].Height.IsStar)
                {
                    availableHeight += minimumHeights[i];
                }
            }
    
            //divide any leftover available height proportionally amongst the star-sized rows, while there's height left to be had
            double totalStarValues = 0;
            for (int i = 0; i < desiredHeights.Length; i++)
            {
                if (this.RowDefinitions[i].Height.IsStar)
                {
                    totalStarValues += this.RowDefinitions[i].Height.Value;
                }
            }
    
            for (int i = 0; i < desiredHeights.Length; i++)
            {
                if (this.RowDefinitions[i].Height.IsStar)
                {
                    finalHeights[i] = availableHeight * (this.RowDefinitions[i].Height.Value / totalStarValues);
                }
            }
    
            //decide the vertical position of each row
            double[] rowPositions = new double[desiredHeights.Length];
            rowPositions[0] = 0;
            for (int i = 1; i < rowPositions.Length; i++)
            {
                rowPositions[i] = rowPositions[i - 1] + finalHeights[i - 1];
            }
    
            //tell children to lay themselves out based on these results
            foreach (UIElement child in this.InternalChildren)
            {
                int row = Grid.GetRow(child);
    
                //special case for scrollviewer, which doesn't size itself appropriately
                if (child is ScrollViewer)
                {
                    ScrollViewer scrollViewer = child as ScrollViewer;
    
                    //temporarily update its height value, JUST for the Arrange() call
                    double oldHeight = scrollViewer.Height;
                    scrollViewer.Height = finalHeights[row];
                    child.Arrange(new Rect(0, rowPositions[row], arrangeSize.Width, finalHeights[row]));
    
                    //restore the original value
                    scrollViewer.Height = oldHeight;
                }
    
                //typical case for non-scroll-viewers
                else
                {
                    child.Arrange(new Rect(0, rowPositions[row], arrangeSize.Width, finalHeights[row]));
                }
            }
    
            return arrangeSize;
        }
    }
    

    Here’s a test case. Drop this in a Window and resize the window to see it working.

    <local:NoStretchGrid VerticalAlignment="Stretch">
    
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="2*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="50"/>
        </Grid.RowDefinitions>
    
        <ScrollViewer VerticalScrollBarVisibility="Visible" MinHeight="50">
            <Rectangle Fill="Orange" Height="250"/>
        </ScrollViewer>
    
        <ScrollViewer VerticalScrollBarVisibility="Visible" Grid.Row="1" MinHeight="50">
            <Rectangle Fill="Blue" Height="200"/>
        </ScrollViewer>
    
        <Grid Background="Pink" Grid.Row="2" MinHeight="30"/>
        <Grid Background="Green" Grid.Row="3" MinHeight="30"/>
        <Grid Background="Red" Grid.Row="4"/>
    
    </local:NoStretchGrid>
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm wondering what would be the typical scenario for using an end-user report designer.
Scenario: I'm currently writing a layer to abstract 3 similar webservices into one useable
Has anyone tried creating end user (potentially online, potentially to be printed) help/documentation out
Very common scenario using Ajax is to parse the response and create the user
I have a website with the following architecture: End user ---> Server A (PHP)
Here's a scenario: I have a java front end (RCP/SWT) app which currently has
Considering the set up: Ms Access Application split into Front End and Back End
I have the requirement that the end-user can change localized resources and the changes
I'm writing an rspec scenario thats failing with: (#<User:0x1056904f0>).update_attributes(#<RSpec::Mocks::ArgumentMatchers::AnyArgMatcher:0x105623648>) expected: 1 time received: 0
Scenario: A stored procedure receives from code a DateTime with, let's say DateTime.Now value,

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.