WPF中的包装板

WPF中的包装板,wpf,xaml,Wpf,Xaml,我的窗口中有以下布局: 网格有两列 GridSplitter用于调整网格列的大小 第二个网格列填充了StackPanel StackPanel垂直定向,有两个子项:TextBlock和一个WrapPanel WrapPanel有两个Grids作为子项 第一个网格子项包含一个图像 第二个Grid包含一个StackPanel,其中3个TextBlocks垂直排列 XAML代码如下所示: <Window> <Grid> <Grid.ColumnDefiniti

我的窗口中有以下布局:

  • 网格
    有两列
  • GridSplitter
    用于调整网格列的大小
  • 第二个网格列填充了
    StackPanel
  • StackPanel
    垂直定向,有两个子项:
    TextBlock
    和一个
    WrapPanel
  • WrapPanel
    有两个
    Grid
    s作为子项
  • 第一个
    网格
    子项包含一个
    图像
  • 第二个
    Grid
    包含一个StackPanel,其中3个
    TextBlock
    s垂直排列 XAML代码如下所示:

    <Window>
      <Grid>
        <Grid.ColumnDefinitions>
          <ColumnDefinition />
          <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <GridSplitter Grid.Column="1" Width="5" HorizontalAlignment="Left" />
        <StackPanel Grid.Column="1" Margin="5,0,0,0" Orientation="Vertical" 
            HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
          <TextBlock Text="Now here's a silly poem for you." />
          <WrapPanel>
            <Grid Name="GridForImage">
              <Image Width="200" Height="200" Source="Image.jpg" />
            </Grid>
            <Grid Name="GridForText">
              <StackPanel Orientation="Vertical">
                <TextBlock TextWrapping="WrapWithOverflow" Text="Roses are red." />
                <TextBlock TextWrapping="WrapWithOverflow" Text="Violets are blue." />
                <TextBlock TextWrapping="WrapWithOverflow" Text="You belong in a zoo." />
              </StackPanel>
            </Grid>
          </WrapPanel>
        </StackPanel>
      </Grid>
    </Window>
    
    
    
    窗口打开后,第二列的宽度足以允许网格
    GridForImage
    GirdForText
    水平相邻放置。如果我使用网格拆分器缩小第二列的宽度,则
    GridForText
    网格将在
    GridForImage
    下的某一点放置,这是意料之中的

    以下是我想要实现的目标:

  • 我希望
    GridForText
    在将网格拆分器移到窗口右侧时,将其宽度缩小到一定大小,并保持在
    GridForImage
    右侧。然后,当宽度缩小到某个值时,比如200px,它应该放在
    GridForImage
    下面,即
    WrapPanel
    应该发挥它的魔力。现在,
    GridForText
    根本不会调整大小,当它的当前宽度对于
    WrapPanel
    的宽度太大时,它会被放在下面
  • GridForText
    放在
    GridForImage
    下面时,我希望
    GridForImage
    填充
    WrapPanel
    的整个宽度
    这一切可能吗?我该怎么办?谢谢大家

    您实际上是在尝试使用两种不同的布局模式,因此只需在布局中设置两种不同的状态,然后添加绑定或触发器,以便在需要切换模式时(即宽度=200)在它们之间切换。使用网格是最灵活的,可以让您对相对大小进行更多的控制,但需要更多的设置,在ControlTemplate或DataTemplate中效果最好,您可以使用触发器根据条件一次设置一系列内容

    下面是一个更紧凑的示例,使用带有一些绑定和转换器的UniformGrid。我删除了图像上的固定大小-如果您更关心填充宽度而不是纵横比,请尝试Stretch=“Fill”。我还将一个StackPanel更改为DockPanel,以保持其子对象的垂直拉伸,并在其中一个文本块中添加背景,以显示其实际宽度:

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <GridSplitter Grid.Column="1" Width="5" HorizontalAlignment="Left" />
        <DockPanel Grid.Column="1" Margin="5,0,0,0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
            <TextBlock Text="Now here's a silly poem for you." DockPanel.Dock="Top"/>
            <UniformGrid Rows="{Binding RelativeSource={RelativeSource Self}, Path=ActualWidth, Converter={x:Static local:LayoutModeConverter.Row}, ConverterParameter=200}"
                         Columns="{Binding RelativeSource={RelativeSource Self}, Path=ActualWidth, Converter={x:Static local:LayoutModeConverter.Column}, ConverterParameter=200}">
                <Image Source="Image.jpg" />
    
                <StackPanel Orientation="Vertical">
                    <TextBlock TextWrapping="WrapWithOverflow" Text="Roses are red." Background="Red" />
                    <TextBlock TextWrapping="WrapWithOverflow" Text="Violets are blue." />
                    <TextBlock TextWrapping="WrapWithOverflow" Text="You belong in a zoo." />
                </StackPanel>
            </UniformGrid>
        </DockPanel>
    </Grid>
    

    明亮的非常感谢。我有一个问题:由于您的解决方案涉及到
    UniformGrid
    ,这意味着当内容显示为两行时,两行的高度相同。我更希望这两行仅采用容纳其内容所需的高度。可能吗?我尝试将
    UniformGrid
    替换为
    Grid
    ,并使用
    Grid.Row
    Grid.Column
    Grid.ColumnSpan
    进行操作,但它没有像我预期的那样工作。你能给我一些建议吗?谢谢。请尝试更改内容对象的垂直对齐方式。“拉伸”是默认设置,但任何其他设置只会使用它们所需的空间,而不是容器提供给它们的所有空间。这不起作用。
    UniformGrid
    的本质是使其每个单元格相等。第一个单元格的内容是高度为200px的图像,第二个单元格的内容是3个文本块-即,由于图像高度大于3个文本块的高度,因此统一网格中所有单元格的高度将由图像高度决定。问题在于统一网格的使用,垂直对齐无法解决这一问题:(您应该试试。单元格的大小只是单元格中所包含内容的可用空间量。任何给定元素实际使用的空间由可用空间与所包含元素的宽度/高度、对齐方式和边距设置的组合决定。
    public class LayoutModeConverter : IValueConverter
    {
        public static readonly LayoutModeConverter Row = new LayoutModeConverter { RowMode = true };
        public static readonly LayoutModeConverter Column = new LayoutModeConverter { RowMode = false };
    
        public bool RowMode { get; set; }
    
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            double width = System.Convert.ToDouble(value);
            double targetWidth = System.Convert.ToDouble(parameter);
            if (RowMode)
                return width > targetWidth ? 1 : 2;
            else
                return width > targetWidth ? 2 : 1;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }