ItemsControl 上的边框消失调整大小(使用“stretchpanel") [英] Border disappearing on ItemsControl resize (using "stretchpanel")
问题描述
昨天我问了如何让 ItemsControl 让它的孩子在可用空间中平均分布;在愉快地阅读答案后,我写了(实际上是复制和调整了它)我自己的拉伸板",这正是我想要的.然而,我的孩子应该在他们的右侧有一个边框,只要孩子大于它的内容,它就可以工作.一旦它变小,边界就会消失,我不知道为什么(因此,不修复它).您可以在下面使用 this 示例作为基础.非常感谢.
Yesterday I asked how to get an ItemsControl to have its children equally distributed across the available space; and after happily reading the answer, I wrote (well actually kind of copied and adjusted it) my own "stretchpanel", which does exactly what i want. However my children are supposed to have a border on their right side, which works, as long as the child is bigger than its content. As soon as it gets smaller the border disappears and i can't tell why (and thus, not fix it). Below you can find a simplified version of my view and of the overriden methods from my stretchpanel, using this sample as basis. Thanks a lot in advance.
<Grid Background="Red" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ItemsControl x:Name="HorizontalListBox" Background="Blue" HorizontalAlignment="Left" HorizontalContentAlignment="Left" >
<ItemsControl.Items>
<System:String>Test</System:String>
<System:String>Test</System:String>
<System:String>This demonstrates the problem exceptionally well</System:String>
<System:String>Test</System:String>
<System:String>Test</System:String>
</ItemsControl.Items>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Controls:StretchPanel Orientation="Horizontal" HorizontalAlignment="Stretch"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Background="Yellow" HorizontalAlignment="Stretch">
<TextBlock Text="{Binding}" HorizontalAlignment="Stretch"/>
<Border BorderBrush="Black" BorderThickness="0,0,1,0"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
protected override Size MeasureOverride(Size availableSize)
{
var size = new Size();
SetSide(ref size, GetSide(availableSize));
foreach (UIElement child in Children)
{
child.Measure(availableSize);
SetOtherSide(ref size, Math.Max(GetOtherSide(size), GetOtherSide(child.DesiredSize)));
}
_measureSize = size;
return size;
}
protected override Size ArrangeOverride(Size finalSize)
{
double offset = 0;
var Side = GetSide(_measureSize) / Children.Count;
var Rest = GetSide(_measureSize) % Children.Count;
foreach (UIElement child in Children)
{
double side = Math.Floor(GetSide(_measureSize) / Children.Count);
if (Rest > 0)
{
side++;
Rest--;
}
var final = new Size();
SetSide(ref final, side);
SetOtherSide(ref final, GetOtherSide(finalSize));
child.Arrange(new Rect(GetOffsetPoint(offset), final));
offset += side;
}
return finalSize;
}
推荐答案
如果你像这样编写你的 StretchPanel,它会起作用,它测量其宽度和高度为零的子元素:
It will work if you write your StretchPanel like this, which measure its child elements with zero width and height:
public class StretchPanel : Panel
{
protected override Size MeasureOverride(Size availableSize)
{
foreach (UIElement element in Children)
{
element.Measure(new Size());
}
return new Size();
}
protected override Size ArrangeOverride(Size finalSize)
{
for (int i = 0; i < Children.Count; i++)
{
int x1 = (int)(finalSize.Width / Children.Count * i);
int x2 = (int)(finalSize.Width / Children.Count * (i + 1));
Children[i].Arrange(new Rect(x1, 0, x2 - x1, finalSize.Height));
}
return finalSize;
}
}
然后在 ItemsControl 上设置 HorizontalAlignment="Stretch"
(或者根本不设置它,因为这是默认值).
and then set HorizontalAlignment="Stretch"
(or don't set it at all, since that is the default value) on the ItemsControl.
这篇关于ItemsControl 上的边框消失调整大小(使用“stretchpanel")的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!