控件水平方向和填充父项
本文关键字:填充 水平 方向 控件 | 更新日期: 2023-09-27 18:13:10
我试图横向放置ItemControl中的项目,同时使它们填充父控件。
这是我的XAMl:
<ItemsControl ItemsSource="{Binding AnnualWeatherViewModels}" Visibility="{Binding IsAnnualWeatherViewModels, Converter={StaticResource VisibilityConverter}}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<V:AerosolSimpleWeatherCharacteristicsView DataContext="{Binding}"></V:AerosolSimpleWeatherCharacteristicsView>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
我为ItemsControl.ItemsPanel
尝试的两个变体是:
<StackPanel Orientation="Horizontal"></StackPanel>
:
<DockPanel LastChildFill="False"></DockPanel>
然而,两者都没有达到预期的结果,StackPanel
压缩所有项,DockPanel
将根据LastChildFill
的值,用专用于最后一项的大部分空间填充父控件的空间,或者不填充父控件的空间。
那么我如何布局我的ItemsControl
的项目水平,并让他们填补父控件的空间?
我最终创建了这个自定义控件,正如答案中建议的那样:
public partial class StretchingPanel : Grid
{
public static readonly DependencyProperty OrientationProperty =
DependencyProperty.Register("Orientation", typeof(Orientation), typeof(StretchingPanel), new UIPropertyMetadata(System.Windows.Controls.Orientation.Horizontal));
public static readonly DependencyProperty FillFirstItemProperty =
DependencyProperty.Register("FillFirstItem", typeof(bool), typeof(StretchingPanel), new UIPropertyMetadata(true));
public static readonly DependencyProperty FillFirstItemFactorProperty =
DependencyProperty.Register("FillFirstItemFactor", typeof(double), typeof(StretchingPanel), new UIPropertyMetadata(1.8));
public Orientation Orientation
{
get
{
return (Orientation)GetValue(OrientationProperty);
}
set
{
SetValue(OrientationProperty, value);
}
}
public bool FillFirstItem
{
get
{
return (bool)GetValue(FillFirstItemProperty);
}
set
{
SetValue(FillFirstItemProperty, value);
}
}
public double FillFirstItemFactor
{
get
{
return (double)GetValue(FillFirstItemFactorProperty);
}
set
{
SetValue(FillFirstItemFactorProperty, value);
}
}
protected override void OnVisualChildrenChanged(DependencyObject visualAdded, DependencyObject visualRemoved)
{
if (Orientation == System.Windows.Controls.Orientation.Horizontal)
{
ColumnDefinitions.Clear();
for (int i = 0; i < Children.Count; ++i)
{
var column = new ColumnDefinition();
if (i == 0 && FillFirstItem)
column.Width = new GridLength(FillFirstItemFactor, GridUnitType.Star);
ColumnDefinitions.Add(column);
Grid.SetColumn(Children[i], i);
}
}
else
{
RowDefinitions.Clear();
for (int i = 0; i < Children.Count; ++i)
{
var row = new RowDefinition();
if (i == 0 && FillFirstItem)
row.Height = new GridLength(FillFirstItemFactor, GridUnitType.Star);
RowDefinitions.Add(row);
Grid.SetRow(Children[i], i);
}
}
base.OnVisualChildrenChanged(visualAdded, visualRemoved);
}
public StretchingPanel()
{
InitializeComponent();
}
}
UniformGrid
完成任务。
<ItemsPanelTemplate>
<UniformGrid Rows="1"/>
</ItemsPanelTemplate>
所以你想按比例拉伸项目。如果在标准面板中可以实现,那就是Grid(可以有比例列),这将需要在ItemSource更改后设置ColumnDefinitions。
使用自定义面板很简单:
class ProportionallyStretchingPanel : Panel
{
protected override Size MeasureOverride(Size availableSize)
{
foreach (UIElement child in InternalChildren)
child.Measure(availableSize);
return availableSize;
}
protected override Size ArrangeOverride(Size availableSize)
{
double widthSum = 0.0;
foreach (UIElement child in InternalChildren)
{
widthSum += child.DesiredSize.Width;
}
double x = 0.0;
foreach (UIElement child in InternalChildren)
{
double proportionalWidth = child.DesiredSize.Width / widthSum * availableSize.Width;
child.Arrange(
new Rect(
new Point(x, 0.0),
new Point(x + proportionalWidth, availableSize.Height)));
x += proportionalWidth;
}
return availableSize;
}
}
<ItemsPanelTemplate>
<local:ProportionallyStretchingPanel"/>
</ItemsPanelTemplate>