【问题标题】:How to have the height of a WPF/XAML GridRow set to Auto but still have it limited to the maximum available height of the Grid?如何将 WPF/XAML GridRow 的高度设置为 Auto,但仍将其限制为 Grid 的最大可用高度?
【发布时间】:2016-09-02 08:45:15
【问题描述】:

我有一个 GroupBox(包含一个 ListBox)和一个 Expander,每个都在 Grid 中各自的行中:

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


        <GroupBox Grid.Row="0" Header="My List">
            <ListBox>
                ...
            </ListBox>
        </GroupBox>


        <Expander Grid.Row="1" ScrollViewer.CanContentScroll="True">
            <Expander.Header>
                <TextBlock FontWeight="Bold">My Expander</TextBlock>
            </Expander.Header>

            <StackPanel Margin="5 5 5 5">
                <TextBlock TextWrapping="Wrap">
                    Lots<LineBreak />
                    and<LineBreak />
                    lots<LineBreak />
                    of<LineBreak />
                    lines.
                </TextBlock>
                <TextBlock TextWrapping="Wrap">
                    More <Run FontFamiliy="Courier">Stuff</Run> here.
                </TextBlock>
            </StackPanel>
        </Expander>
    <Grid>

想要的行为:

我希望 GroupBox(带有 ListBox)使用由父级(例如,父级是 Window)定义的 Grid 的所有可用空间减去(关闭的)Expander 的大小。如果用户打开 Expander,它应该让 GroupBox 收缩(甚至完全折叠)并为 Expander 留出空间。

但是,我想将 Expander 的高度限制为允许 Grid 展开而不会导致溢出的最大可用高度。如果 Expander 的高度因此受到限制,它应该开始显示一个垂直滚动条。

当前行为:

使用我当前的 XAML 代码,Expander 将使 Grid 溢出,即它会扩展超出可用空间(因此也不会显示垂直滚动条。)

简而言之:

如何设置 Grid 以将 Expander 的高度限制为 Grid 的最大可用高度?

【问题讨论】:

    标签: wpf xaml


    【解决方案1】:

    第一种解决方案: 我能想到的简单解决方案是用一个只读的 TextBox 代替 Expander->TextBlock 并有 VerticalScrollBarVisibility= Auto 这是示例代码;

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition  />
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <GroupBox Grid.Row="0" Header="My List">
            <ListBox>
                ...
            </ListBox>
        </GroupBox>
    
    
        <Expander Grid.Row="1" ScrollViewer.CanContentScroll="True">
            <Expander.Header>
                <TextBlock FontWeight="Bold">My Expander</TextBlock>
            </Expander.Header>
    
            <StackPanel Margin="5 5 5 5">
                <TextBox TextWrapping="Wrap" Margin="0,0,0,30"  MaxHeight="290" HorizontalAlignment="Left" VerticalScrollBarVisibility="Auto" IsReadOnly="True" >
                    <TextBox.Text>
                        Lorem ipsum dolor sit amet...
                        Very Very long text
    
                    </TextBox.Text>
                </TextBox>
            </StackPanel>
        </Expander>
        </Grid>
    

    您唯一需要注意的是 TextBox 的 MaxHeight。 MaxHeight 应该是(窗口高度 - 扩展器高度)。

    第二个解决方案: 如果必须使用 TextBlock,您可以在 TextBlock 周围包裹一个 scrollViewer 并将其 MaxHeight 设置为(窗口高度 - 扩展器高度)

    首先:添加对你的 XAML Window 的引用

    xmlns:local="cld-namespace:AutoSizing"
    

    第二次:像这样创建一个转换器实例。

    <Window.Resources>
        <local:SizeModifierConverter x:Key="SizeModifierConverter"/>
    </Window.Resources>
    

    第三:在ScrollViewer中使用Binding和Covnverter

           <ScrollViewer VerticalScrollBarVisibility="Auto" 
                          MaxHeight="{Binding Path=ActualHeight, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window},
                          Converter={StaticResource SizeModifierConverter}, ConverterParameter= -50}" >
                <StackPanel Margin="5 5 5 5">
                        <TextBlock TextWrapping="Wrap" Margin="0,0,0,30" Width="20"  HorizontalAlignment="Left" >
                           Long text with Run Linereak and hyperlinks...
                        </TextBlock>
    
                        <TextBlock TextWrapping="Wrap" Margin="0,0,0,30" Width="20"  HorizontalAlignment="Left" >
                           Long text with Run Linereak and hyperlinks...
                        </TextBlock>
                </StackPanel>
            </ScrollViewer>
    

    转换器将如下所示;

    public class SizeModifierConverter : IValueConverter
    {
    
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            double ActualWidth;
            if(double.TryParse(value.ToString(), out ActualWidth))
            {
                double AdjustValue = 0;
                if (double.TryParse(parameter.ToString(), out AdjustValue))
                {
                    return (ActualWidth + AdjustValue);
                }
            }
    
            return value;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return value;
        }
    }
    

    希望这会有所帮助!

    【讨论】:

    • 感谢您的回答。不幸的是,我必须使用 TextBlocks,因为我需要在其中插入 s。 StackPanel 中还有多个 TextBlock。因此,我将无法使用您的答案。但是根据您的回答,我只是在示例中添加了一些细节。
    • 用户很可能会调整窗口大小 - 那么我如何自动确定 MaxHeight 呢?我是否必须绑定它所以一些计算的表达式?如果是,我必须把它放在哪里?
    • 您可以将父级的 ActualHeight 绑定到滚动查看器的最大高度,并且需要转换器将其高度更改为 50。请参阅修改后的答案。
    【解决方案2】:

    我想出了一个不需要任何代码隐藏的解决方案。我的解决方案使用 DockPanel:

        <DockPanel>
            <Expander DockPanel.Dock="Bottom">
                <Expander.Header>
                    <TextBlock FontWeight="Bold">My Expander</TextBlock>
                </Expander.Header>
    
                <ScrollViewer>
                    <StackPanel Margin="5 5 5 5">
                        <TextBlock TextWrapping="Wrap">
                            Lots<LineBreak />
                            and<LineBreak />
                            lots<LineBreak />
                            of<LineBreak />
                            lines.
                        </TextBlock>
                        <TextBlock TextWrapping="Wrap">
                            More <Run FontFamiliy="Courier">Stuff</Run> here.
                        </TextBlock>
                    </StackPanel>
                </ScrollViewer>
            </Expander>
    
    
            <GroupBox Header="My List" DockPanel.Dock="Top">
                <ListBox>
                    ...
                </ListBox>
            </GroupBox>
        <Grid>
    

    【讨论】:

      猜你喜欢
      • 2011-01-05
      • 2016-01-20
      • 1970-01-01
      • 2017-11-27
      • 2021-05-17
      • 1970-01-01
      • 2011-09-27
      • 1970-01-01
      • 2019-07-01
      相关资源
      最近更新 更多