我已经制作了一个自定义面板,类似于WrapPanel但具有列(或像Grid一样,但是项目会自动在网格中定位)。
这就是它的外观:
我想在我的面板上有一个属性,可以在每个列之间绘制一条线。是否可以在自定义面板上进行绘制?
我希望得到的结果类似于这样(请注意黑线):
编辑:如果我让窗口变宽,面板将自动创建更多列,因此分隔符线必须是动态的-也就是说,可能是零、一个、两个、三个或更多的分隔符线。
这是我面板的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
namespace WpfApplication26
{
public class AutoSizingColumnsWrapPanel : Panel
{
public double MinColumnWidth { get; set; }
//public bool ShowColumnSeparator { get; set; }
public AutoSizingColumnsWrapPanel()
{
MinColumnWidth = 100;
}
protected override System.Windows.Size MeasureOverride(System.Windows.Size availableSize)
{
return DoLayout(availableSize, (uiElement, size, pos) => uiElement.Measure(size));
}
protected override System.Windows.Size ArrangeOverride(System.Windows.Size finalSize)
{
return DoLayout(finalSize, (uiElement, size, pos) => uiElement.Arrange(pos));
}
private Size DoLayout(Size availableSize, Action<UIElement, Size, Rect> layoutAction)
{
// Calculate number of columns and column width
int numberOfColumns = 0;
double columnWidth = MinColumnWidth;
if (double.IsInfinity(availableSize.Width))
{
numberOfColumns = InternalChildren.Count;
}
else
{
numberOfColumns = (int)Math.Max(Math.Floor(availableSize.Width / MinColumnWidth), 1);
columnWidth = availableSize.Width / numberOfColumns;
}
// Init layout parameters
Size measureSize = new Size(columnWidth, availableSize.Height);
int currentColumn = 0;
int currentRow = 0;
double currentY = 0;
double currentRowHeight = 0;
// Place all items.
foreach (UIElement item in InternalChildren)
{
var position = new Rect(currentColumn++ * columnWidth, currentY, columnWidth, item.DesiredSize.Height);
// Execute action passing: item = The child item to layout | measureSize = The size allocated for the child item | position = The final position and height of the child item.
layoutAction(item, measureSize, position);
// Keep the highest item on the row (so that we know where to start the next row).
currentRowHeight = Math.Max(currentRowHeight, item.DesiredSize.Height);
if (currentColumn == numberOfColumns)
{
// The item placed was in the last column. Increment/reset layout counters.
currentRow++;
currentColumn = 0;
currentY += currentRowHeight;
currentRowHeight = 0;
}
}
// Return total size of the items/panel.
return new Size(numberOfColumns * columnWidth, currentY + currentRowHeight);
}
}
}
这是我的 WPF 窗口,用于托管该面板:
<Window x:Class="WpfApplication26.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication26"
Title="MainWindow" Height="350" Width="525">
<local:AutoSizingColumnsWrapPanel MinColumnWidth="200" VerticalAlignment="Top">
<TextBlock Text="One" Background="AliceBlue"/>
<DockPanel >
<TextBlock Text="Two: " Background="Beige"/>
<TextBox HorizontalAlignment="Stretch" />
</DockPanel>
<TextBlock Text="Three" Background="DarkKhaki"/>
<TextBlock Text="Four" Background="AliceBlue"/>
<TextBlock Text="Five" Background="Beige" Height="50"/>
<TextBlock Text="Six" Background="DarkKhaki"/>
<TextBlock Text="Seven" Background="AliceBlue"/>
<TextBlock Text="Eight" Background="Beige"/>
<TextBlock Text="Nine" Background="DarkKhaki"/>
<TextBlock Text="Ten" Background="AliceBlue"/>
<TextBlock Text="Eleven" Background="Beige"/>
</local:AutoSizingColumnsWrapPanel>
</Window>
BorderThickness="0,0,1,0"
的值来实现。 - ywm