.net 具有每行最小高度的UniformGrid
我的应用程序在.net 具有每行最小高度的UniformGrid,.net,wpf,layout,.net,Wpf,Layout,我的应用程序在ItemsControl中显示多个项目,该控件使用UniformGrid作为其ItemsPanel <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <!-- Arrange all items vertically, distribute the space evenly --> <UniformGrid Columns="1"/> <
ItemsControl
中显示多个项目,该控件使用UniformGrid
作为其ItemsPanel
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<!-- Arrange all items vertically, distribute the space evenly -->
<UniformGrid Columns="1"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
所以这也不起作用
在可视化树上行走可能也不是一个选项,因为为时已晚。我需要先设置最小高度,然后再安排项目面板,这样它就不会闪烁。(我在更改大小时生成复杂内容,因此必须避免任何延迟布局。)
我需要什么样的选择才能得到我所需要的
如果可能的话,我可能会放弃UniformGrid,而选择其他内容。有什么建议吗?A
UniformGrid
执行一项非常精确的任务。。。为所有项目提供完全相同大小的空间以进行渲染。如果不需要该功能,则使用的面板不正确。请尝试使用,它可以更好地处理不同大小的孩子:
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
您可以使用许多技术来实现这一点。然而,在方法上,我们需要扩展UniformGrid
这种情况下的解决方案是重写MeasureOverride()
,根据行中所有子项的最小高度或最小行高计算新的大小,该值越大越好
用法:
<UserControl x:Class="SOF.UniformGridMinHeight"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:sof="clr-namespace:SOF"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<sof:UniformGridEx Columns="3" MinRowHeight="100">
<Border Background="Red"/>
<Border Background="Blue"/>
<Border Background="Green"/>
<Border Background="Yellow"/>
<Border Background="Pink"/>
<Border Background="Purple"/>
<Border Background="LightCoral"/>
<Border Background="DimGray"/>
<Border Background="OrangeRed"/>
<Border Background="Olive"/>
<Border Background="Salmon"/>
</sof:UniformGridEx>
扩展的UniformGrid:
public class UniformGridEx : UniformGrid
{
public static readonly DependencyProperty MinRowHeightProperty = DependencyProperty.Register(
"MinRowHeight", typeof(double), typeof(UniformGrid), new FrameworkPropertyMetadata(0d, FrameworkPropertyMetadataOptions.AffectsMeasure));
private int _columns;
private int _rows;
public double MinRowHeight
{
get { return (double)GetValue(MinRowHeightProperty); }
set { SetValue(MinRowHeightProperty, value); }
}
protected override Size MeasureOverride(Size constraint)
{
UpdateComputedValues();
var calculatedSize = base.MeasureOverride(constraint);
if (MinRowHeight > 0)
{
calculatedSize = new Size(calculatedSize.Width, Math.Max(calculatedSize.Height, _rows * MinRowHeight));
}
return calculatedSize;
}
private void UpdateComputedValues()
{
_columns = Columns;
_rows = Rows;
if (FirstColumn >= _columns)
{
FirstColumn = 0;
}
if ((_rows == 0) || (_columns == 0))
{
int nonCollapsedCount = 0;
for (int i = 0, count = InternalChildren.Count; i < count; ++i)
{
UIElement child = InternalChildren[i];
if (child.Visibility != Visibility.Collapsed)
{
nonCollapsedCount++;
}
}
if (nonCollapsedCount == 0)
{
nonCollapsedCount = 1;
}
if (_rows == 0)
{
if (_columns > 0)
{
_rows = (nonCollapsedCount + FirstColumn + (_columns - 1)) / _columns;
}
else
{
_rows = (int)Math.Sqrt(nonCollapsedCount);
if ((_rows * _rows) < nonCollapsedCount)
{
_rows++;
}
_columns = _rows;
}
}
else if (_columns == 0)
{
_columns = (nonCollapsedCount + (_rows - 1)) / _rows;
}
}
}
}
公共类UniformGridEx:UniformGrid
{
公共静态只读DependencyProperty MinRowHeightProperty=DependencyProperty.Register(
“最小行高”、typeof(double)、typeof(UniformGrid)、新的FrameworkPropertyMetadata(0d,FrameworkPropertyMetadata选项。影响度量));
专用int_列;
私有整数行;
公共双排高度
{
获取{return(double)GetValue(MinRowHeightProperty);}
set{SetValue(MinRowHeightProperty,value);}
}
受保护的覆盖尺寸测量覆盖(尺寸约束)
{
updateComputerdValues();
var calculatedSize=基本测量值超出(约束);
如果(最小行高>0)
{
calculatedSize=新大小(calculatedSize.Width,Math.Max(calculatedSize.Height,_rows*MinRowHeight));
}
返回计算的大小;
}
私有void updateComputerdValues()
{
_列=列;
_行=行;
如果(第一列>=\u列)
{
第一列=0;
}
如果(_行==0)| |(_列==0))
{
int noncollecsedCount=0;
for(int i=0,count=InternalChildren.count;i0)
{
_行=(nonCollapsedCount+FirstColumn+(\u columns-1))/\u列;
}
其他的
{
_行=(int)Math.Sqrt(nonCollapsedCount);
if((_行*_行)
我发现我不久前已经用以下代码解决了这个问题。我的应用程序中有一个派生类,因此我可以重写ItemsControl
的MeasureOverride
方法
class MyItemsControl : ItemsControl
{
// ...
protected override Size MeasureOverride(Size constraint)
{
Size size = base.MeasureOverride(constraint);
// Keep minimum height per item
int minHeight = Items.Count * 250;
if (size.Height < minHeight)
{
size.Height = minHeight;
}
return size;
}
}
类MyItemsControl:ItemsControl
{
// ...
受保护的覆盖尺寸测量覆盖(尺寸约束)
{
尺寸=基准测量超越(约束);
//保持每件物品的最低高度
int minHeight=Items.Count*250;
如果(尺寸高度<最小高度)
{
尺寸。高度=最小高度;
}
返回大小;
}
}
我的类的XAML代码如下所示:
<ItemsControl x:Class="MyItemsControl">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<!-- Arrange all items vertically, distribute the space evenly -->
<UniformGrid Columns="1"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!-- Templates and other stuff ... -->
</ItemsControl>
查看答案,看看是否有用。只要有足够的空间,我就需要填充功能。即使空间太小,也应该在所有物品之间均匀分布。他们需要伸展整个宽度。包装袋永远无法做到这一点,它总是将物品保持尽可能小。
<ItemsControl x:Class="MyItemsControl">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<!-- Arrange all items vertically, distribute the space evenly -->
<UniformGrid Columns="1"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!-- Templates and other stuff ... -->
</ItemsControl>