WPF网格-以最小高度限制自动调整大小 [英] WPF Grid - Auto-sizing with minimum height constraints

查看:135
本文介绍了WPF网格-以最小高度限制自动调整大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景

我需要一个具有以下布局属性的网格:

  1. 4行:页眉,主要内容,子内容,页脚
  2. 标题是静态内容,实际上不受大小调整的影响
  3. 主要内容需要填满所有可用空间,且最小高度为180
  4. 子内容是可以缩小和增长的实时出价.此子内容可能会占用一些主要内容空间,但应始终为主要内容保留180个像素.理想情况下,子内容仅应占用其所需的最小面积.如果网格中没有剩余空间,则实时出价应停止增长,而应启用其内部滚动查看器.
  5. 页脚就像页眉一样,静态内容不受大小调整的影响

问题

子内容(RTB)不会自动调整大小以适合剩余空间,也不会启用垂直滚动条.这导致主要内容下方的所有内容都被裁剪到窗口外部.

问题

如何缩小RichTextBox以便显示页脚,从而允许用户滚动显示隐藏的RichTextBox内容,同时如果用户拉伸窗口,同时允许RichTextBox展开? /p>

在下面,您将找到一个SSCCE,该SSCCE演示了我正在尝试实现的目标以及所引起的问题:

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        MinWidth="200" MinHeight="300" Width="200" Height="300">

    <Grid>

        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*" MinHeight="180"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="10"/>
        </Grid.RowDefinitions>

        <TextBlock Grid.Row="0" Text="Header" HorizontalAlignment="Center"/>

        <Rectangle Grid.Row="1" Fill="Red"/>

        <RichTextBox Grid.Row="2"
                     VerticalScrollBarVisibility="Visible"
                     Height="Auto"
                     Margin="0,5,0,0"
                     VerticalAlignment="Stretch"
                     BorderBrush="#FF818181"
                     BorderThickness="0.5"
                     Background="#FFEEEEEE"
                     FontSize="14">
            <FlowDocument>
                <List>
                    <ListItem>
                        <Paragraph>Lorem</Paragraph>
                        <Paragraph>IpSum</Paragraph>
                        <Paragraph>Lorem</Paragraph>
                        <Paragraph>IpSum</Paragraph>
                    </ListItem>
                </List>
            </FlowDocument>
        </RichTextBox>

        <TextBlock Grid.Row="3" Text="Footer" HorizontalAlignment="Center"/>

    </Grid>
</Window>

这是窗口的最小尺寸图片:

这是窗口被拉伸以显示所有内容时的图像:

其他信息

我知道,如果将子内容RowDefinition设置为*,则RichTextBox可以正常工作,除外,因为扩展窗口时会占用太多空间.我需要这个区域在容纳Auto的同时要占用Auto的空间.

解决方案

分而治之

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication2"
        MinWidth="200" MinHeight="300" Width="200" Height="300">
    <Window.Resources>
        <local:HeightConverter x:Key="HeightConverter" />
    </Window.Resources>

    <!--MainGrid-->
    <Grid Name="grid">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

    <!--AlignmentGrid-->
        <Grid Grid.Row="0">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*" MinHeight="180"/>
                <RowDefinition Height="Auto">
                </RowDefinition>
            </Grid.RowDefinitions>
            <TextBlock Name="head" Grid.Row="0" Text="Header" HorizontalAlignment="Center"/>
            <Rectangle Name="rect" Grid.Row="1" Fill="Red"/>
            <RichTextBox Grid.Row="2"
                         VerticalScrollBarVisibility="Visible"
                         Margin="0,5,0,0"
                         VerticalAlignment="Stretch"
                         BorderBrush="#FF818181"
                         BorderThickness="0.5"
                         Background="#FFEEEEEE"
                         FontSize="14">
                <RichTextBox.MaxHeight>
                    <MultiBinding Converter="{StaticResource HeightConverter}">
                        <Binding ElementName="grid" Path="ActualHeight"/>
                        <Binding ElementName="head" Path="ActualHeight"/>
                        <Binding ElementName="rect" Path="ActualHeight"/>
                        <Binding ElementName="foot" Path="ActualHeight"/>
                    </MultiBinding>
                </RichTextBox.MaxHeight>
                <FlowDocument>
                    <List>
                        <ListItem>
                            <Paragraph>Lorem</Paragraph>
                            <Paragraph>IpSum</Paragraph>
                            <Paragraph>Lorem</Paragraph>
                            <Paragraph>IpSum</Paragraph>
                        </ListItem>
                    </List>
                </FlowDocument>
            </RichTextBox>
        </Grid>

    <!--Footer-->
        <TextBlock Name="foot" Grid.Row="1" Text="Footer" HorizontalAlignment="Center"/>
    </Grid>
</Window>

转换器:

public class HeightConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        double gridHeight = (double)values[0];
        double headHeight = (double)values[1];
        double rectHeight = (double)values[2];
        double footHeight = (double)values[3];

        return gridHeight - headHeight - rectHeight - footHeight;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

请注意,为了使Converter获得所需的结果,MainGrid的高度不得超过Window中内容的高度.

Background

I need a grid with the following layout properties:

  1. 4 rows: header, main content, sub-content, footer
  2. The header is static content which isn't really affected by resize
  3. The main content needs to fill up all available space, with a minimum height of 180
  4. The sub-content is a RTB that can shrink and grow. This sub-content can eat up some of the main-contents space, but should always leave 180 pixels for the main-content. The sub-content should ideally only take up the minimum amount of area it needs. If there isn't much room left in the grid, the RTB should stop growing and instead enable its internal scrollviewer.
  5. The footer is like the header, static content unaffected by resize

The problem

The sub-content (RTB) isn't auto-sizing itself to fit within the remaining space, nor is the vertical scroll-bar being enabled. This is causing anything below the main content to clip outside of the window.

Question

How can I get the RichTextBox to shrink so that the footer is shown, allowing the user to scroll through the hidden RichTextBox content, while simultaneously allowing the RichTextBox to expand if the user stretches the window?

Below you will find a SSCCE which demonstrates what I'm trying to achieve and the issues that it's causing:

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        MinWidth="200" MinHeight="300" Width="200" Height="300">

    <Grid>

        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*" MinHeight="180"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="10"/>
        </Grid.RowDefinitions>

        <TextBlock Grid.Row="0" Text="Header" HorizontalAlignment="Center"/>

        <Rectangle Grid.Row="1" Fill="Red"/>

        <RichTextBox Grid.Row="2"
                     VerticalScrollBarVisibility="Visible"
                     Height="Auto"
                     Margin="0,5,0,0"
                     VerticalAlignment="Stretch"
                     BorderBrush="#FF818181"
                     BorderThickness="0.5"
                     Background="#FFEEEEEE"
                     FontSize="14">
            <FlowDocument>
                <List>
                    <ListItem>
                        <Paragraph>Lorem</Paragraph>
                        <Paragraph>IpSum</Paragraph>
                        <Paragraph>Lorem</Paragraph>
                        <Paragraph>IpSum</Paragraph>
                    </ListItem>
                </List>
            </FlowDocument>
        </RichTextBox>

        <TextBlock Grid.Row="3" Text="Footer" HorizontalAlignment="Center"/>

    </Grid>
</Window>

Here is an image of the window when it's at its minimum size:

Here is an image of the window when it has been stretched to show all:

Extra information

I know that if I set the sub-content RowDefinition to * then the RichTextBox works fine, except for the fact it takes too much room when the window is expanded. I need this area to take as much room as Auto while behaving like *.

解决方案

Divide and conquer

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication2"
        MinWidth="200" MinHeight="300" Width="200" Height="300">
    <Window.Resources>
        <local:HeightConverter x:Key="HeightConverter" />
    </Window.Resources>

    <!--MainGrid-->
    <Grid Name="grid">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

    <!--AlignmentGrid-->
        <Grid Grid.Row="0">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*" MinHeight="180"/>
                <RowDefinition Height="Auto">
                </RowDefinition>
            </Grid.RowDefinitions>
            <TextBlock Name="head" Grid.Row="0" Text="Header" HorizontalAlignment="Center"/>
            <Rectangle Name="rect" Grid.Row="1" Fill="Red"/>
            <RichTextBox Grid.Row="2"
                         VerticalScrollBarVisibility="Visible"
                         Margin="0,5,0,0"
                         VerticalAlignment="Stretch"
                         BorderBrush="#FF818181"
                         BorderThickness="0.5"
                         Background="#FFEEEEEE"
                         FontSize="14">
                <RichTextBox.MaxHeight>
                    <MultiBinding Converter="{StaticResource HeightConverter}">
                        <Binding ElementName="grid" Path="ActualHeight"/>
                        <Binding ElementName="head" Path="ActualHeight"/>
                        <Binding ElementName="rect" Path="ActualHeight"/>
                        <Binding ElementName="foot" Path="ActualHeight"/>
                    </MultiBinding>
                </RichTextBox.MaxHeight>
                <FlowDocument>
                    <List>
                        <ListItem>
                            <Paragraph>Lorem</Paragraph>
                            <Paragraph>IpSum</Paragraph>
                            <Paragraph>Lorem</Paragraph>
                            <Paragraph>IpSum</Paragraph>
                        </ListItem>
                    </List>
                </FlowDocument>
            </RichTextBox>
        </Grid>

    <!--Footer-->
        <TextBlock Name="foot" Grid.Row="1" Text="Footer" HorizontalAlignment="Center"/>
    </Grid>
</Window>

The Converter:

public class HeightConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        double gridHeight = (double)values[0];
        double headHeight = (double)values[1];
        double rectHeight = (double)values[2];
        double footHeight = (double)values[3];

        return gridHeight - headHeight - rectHeight - footHeight;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Note that for the Converter to give the desired result, the height of the MainGrid may not exceed the height of the content in the Window.

这篇关于WPF网格-以最小高度限制自动调整大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆