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();
}
}