我的窗口中有以下XAML:
<WrapPanel>
<WrapPanel.Resources>
<Style TargetType="Rectangle">
<Setter Property="Margin" Value="10,10,10,10"/>
<Setter Property="VerticalAlignment" Value="Top"/>
</Style>
</WrapPanel.Resources>
<Rectangle Height="100" Width="100" Fill="Red"/>
<Rectangle Height="200" Width="200" Fill="Yellow"/>
<Rectangle Height="150" Width="150" Fill="Green"/>
<Rectangle Height="50" Width="50" Fill="Blue"/>
<Rectangle Height="250" Width="250" Fill="Purple"/>
</WrapPanel>
我正在寻找的是一种水平对齐的方法。包装面板中的子元素,以便窗口看起来像这样:
有没有办法在包装面板中实现这一点,还是我需要考虑使用其他控件或编写自定义控件?
答案 0 :(得分:1)
看起来你想要的是一个包含行和列的网格。
<Grid>
<Grid.Resources>
<Style TargetType="Rectangle">
<Setter Property="Margin" Value="10,10,10,10"/>
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Rectangle Height="100" Width="100" Fill="Red" Grid.Column="0"/>
<Rectangle Height="200" Width="200" Fill="Yellow" Grid.Column="1"/>
<Rectangle Height="150" Width="150" Fill="Green" Grid.Column="2"/>
<Rectangle Height="50" Width="50" Fill="Blue" Grid.Column="3"/>
<Rectangle Height="250" Width="250" Fill="Purple" Grid.Row="1"/>
</Grid>
这可以实现第二张图片的精确布局,但不会随着窗口大小的变化而换行。要做到这一点,您可能需要一个自定义Grid控件,可以在调整容器大小时动态排列子项。
答案 1 :(得分:1)
使用一些不同的技术,您可以到达您想要的位置。这个SO answer显示了如何定义响应列宽:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="3*"/>
<RowDefinition Height="2*"/>
<RowDefinition Height="3*"/>
</Grid.RowDefinitions>
如果这还不够,你可以走自己的路径,拥有一个使用网格布局的自定义控件,并重新定位每个子控件当前所在的列/行,以及控件或窗口调整大小事件,重做基于列/像素计算的布局定位。
<强>更新强>
对于自定义控件,您可以尝试类似于此的内容:
public class CustomLayout:Control { 私人列表儿童;
public CustomLayout()
{
children = new List<Control>();
}
public void AddChild(Control childToAdd)
{
children.Add(childToAdd);
// TODO: Determine if new layout is needed.
}
public void RemoveChild(Control childToRemove)
{
children.Remove(childToRemove);
// TODO: Determine if new layout is needed.
}
// Call to update the layout.
private void PerformLayout(int columns, int rows)
{
Grid layoutGrid = new Grid();
// TODO: Programmatically build grid layout.
RowDefinition row = new RowDefinition();
row.Height = 100;
layoutGrid.Rows.Add(row);
// Methods for layout:
// Grid.SetRow(rowID, childControl);
// Grid.SetColumn(columnID, childControl);
// Note: This may produce some flashing on resize, so there may be better ways to remove/add the grid such as redoing rows and columns instead.
Controls.Clear();
Controls.Add(layoutGrid);
}
// Should be called when the window or parent resizes. I can't remember the events in question.
public void OnResize()
{
int columns;
int rows;
// TODO: Calculate columns/rows
PerformLayout(columns, rows);
}
}
希望这能让你朝着正确的方向前进。请记住,这是伪代码,可能无法完全编译。