Silverlight布局与页面尺寸管理
立即解锁
发布时间: 2025-08-26 01:40:44 阅读量: 5 订阅数: 26 

### Silverlight布局与页面尺寸管理
#### 1. 均匀网格(UniformGrid)
均匀网格是一种自定义布局容器,它能将子元素排列到自动生成的等大小单元格中。与常规网格相比,它无需明确定义行和列,也不必手动将每个子元素放置到正确的单元格中,在显示一组平铺图像时非常实用。
##### 1.1 类声明
均匀网格继承自`System.Windows.Controls.Panel`类,其声明如下:
```csharp
public class UniformGrid : System.Windows.Controls.Panel
{ ... }
```
如果想在多个应用程序中重用该自定义布局容器,建议将其放在一个新的Silverlight类库中,使用时只需添加对编译后的类库的引用。
##### 1.2 属性与布局逻辑
均匀网格有两个属性`Rows`和`Columns`,可独立设置或组合设置,它们对布局逻辑的影响如下:
- **两者都设置**:均匀网格根据设置的行和列大小划分可用空间,确定每个单元格的大小。若元素数量多于单元格数量,多余元素将不显示。
- **仅设置一个属性**:假设要显示所有元素,均匀网格会计算另一个属性的值。例如,设置`Columns`为3,放入8个元素,则会将可用空间划分为3行。
- **两者都未设置**:假设要显示所有元素且行和列数量相等,均匀网格会计算行和列的数量。若无法使行和列数量完全匹配,会额外添加一列。
##### 1.3 代码实现
为实现上述布局逻辑,均匀网格会跟踪实际的行和列数量。若未设置`Rows`和`Columns`属性,会使用`CalculateColumns()`方法计算:
```csharp
private int realColumns;
private int realRows;
private void CalculateColumns()
{
double elementCount = this.Children.Count;
if (elementCount == 0) return;
realRows = Rows;
realColumns = Columns;
if ((realRows != 0) && (realColumns != 0))
return;
if ((realColumns == 0) && realRows == 0)
realColumns = (int)Math.Ceiling(Math.Sqrt(elementCount));
if (realColumns == 0)
realColumns = (int)Math.Ceiling(elementCount / realRows);
if (realRows == 0)
realRows = (int)Math.Ceiling(elementCount / realColumns);
}
```
Silverlight布局系统通过调用`MeasureOverride()`方法开始布局过程,该方法会调用`CalculateColumns()`方法,并将可用空间划分为等大小的单元格:
```csharp
protected override Size MeasureOverride(Size constraint)
{
CalculateColumns();
Size childConstraint = new Size(
constraint.Width / realColumns, constraint.Height / realRows);
Size largestCell = new Size();
foreach (UIElement child in this.Children)
{
child.Measure(childConstraint);
largestCell.Height = Math.Max(largestCell.Height, child.DesiredSize.Height);
largestCell.Width = Math.Max(largestCell.Width, child.DesiredSize.Width);
}
return new Size(largestCell.Width * realColumns, largestCell.Height * realRows);
}
```
`ArrangeOverride()`方法负责记录最终的空间测量值,计算单元格大小,并将每个子元素放置在适当的边界内:
```csharp
protected override Size ArrangeOverride(Size arrangeSize)
{
double cellWidth = arrangeSize.Width / realColumns;
double cellHeight = arrangeSize.Height / realRows;
Rect childBounds = new Rect(0, 0, cellWidth, cellHeight);
foreach (UIElement child in this.Children)
{
child.Arrange(childBounds);
childBounds.X += cellWidth;
if (childBounds.X >= cellWidth * realColumns)
{
childBounds.Y += cellHeight;
childBounds.X = 0;
if (childBounds.Y >= cellHeight * realRows)
childBounds = new Rect(0, 0, 0, 0);
}
}
```
0
0
复制全文
相关推荐










