我有一个自定义控件ListBox,我想根据其ItemsPanel的大小调整其大小。对于items面板,我有一个自定义控件WrapPanel,可以相应地排列项目。正如您在屏幕截图中看到的那样,ListBox更喜欢将自身大小调整为其父控件或availableSize。
然后我尝试创建一个自定义控件Grid,它有一个ItemsSource属性,将项目传递给它的列表框。但这也不起作用。当网格排列时,ListBox会排列,这将导致网格排列等等。
所以我的问题是,如何创建一个具有ItemsSource属性的自定义控件和一个根据子元素的内容调整自身大小的ItemsPresenter?
答案 0 :(得分:1)
您只需将ListBox HorizontalAlignment设置为Left,将VerticalAlignment设置为Top。这应该可以解决问题。
简单示例:
MainWindow.xaml
<Window x:Class="ListBoxFitItemsPanel.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="400" Width="400">
<ListBox ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled" Background="Red" HorizontalAlignment="Left" VerticalAlignment="Top" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Background="AntiqueWhite" Margin="5" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<Rectangle Width="100" Height="100" Fill="LightSlateGray" Stroke="Black" StrokeThickness="1" Margin="5" />
<Rectangle Width="100" Height="100" Fill="LightSlateGray" Stroke="Black" StrokeThickness="1" Margin="5" />
<Rectangle Width="100" Height="100" Fill="LightSlateGray" Stroke="Black" StrokeThickness="1" Margin="5" />
<Rectangle Width="100" Height="100" Fill="LightSlateGray" Stroke="Black" StrokeThickness="1" Margin="5" />
<Rectangle Width="100" Height="100" Fill="LightSlateGray" Stroke="Black" StrokeThickness="1" Margin="5" />
<Rectangle Width="100" Height="100" Fill="LightSlateGray" Stroke="Black" StrokeThickness="1" Margin="5" />
<Rectangle Width="100" Height="100" Fill="LightSlateGray" Stroke="Black" StrokeThickness="1" Margin="5" />
<Rectangle Width="100" Height="100" Fill="LightSlateGray" Stroke="Black" StrokeThickness="1" Margin="5" />
<Rectangle Width="100" Height="100" Fill="LightSlateGray" Stroke="Black" StrokeThickness="1" Margin="5" />
</ListBox>
</Window>
编辑:它也适用于绑定方案:
<强> MainWindow.xaml 强>
<Window x:Class="ListBoxFitItemsPanel.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ListBoxFitItemsPanel"
Title="MainWindow" Height="400" Width="400">
<Window.Resources>
<DataTemplate DataType="{x:Type local:Item}">
<Rectangle Width="100" Height="100" Fill="LightSlateGray" Stroke="Black" StrokeThickness="1" Margin="5" />
</DataTemplate>
</Window.Resources>
<ListBox ItemsSource="{Binding Items}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled" Background="Red" HorizontalAlignment="Left" VerticalAlignment="Top" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Background="AntiqueWhite" Margin="5" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</Window>
<强> MainWindow.xaml.cs 强>
using System.Collections.Generic;
using System.Windows;
namespace ListBoxFitItemsPanel
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
public IEnumerable<Item> Items
{
get
{
for (int i = 0; i < 9; i++)
{
yield return new Item();
}
}
}
}
public class Item { }
}
答案 1 :(得分:1)
这是我必须要做的,以获得我想要的功能。首先,我必须创建我的SquareWrapPanel。这就是魔术发生的地方,并按照我想要的方式安排我的物品。
protected override Size ArrangeOverride(Size finalSize)
{
return ArrangeByChildCount(finalSize);
}
private Size ArrangeByChildCount(Size finalSize)
{
double childWidth = 0;
double childHeight = 0;
foreach (UIElement e in Children)
{
e.Measure(finalSize);
childWidth = e.DesiredSize.Width;
childHeight = e.DesiredSize.Height;
}
if (Children.Count > 0)
{
int square = (int)Math.Sqrt(Children.Count);
int rowCount = square + Children.Count % square;
int columnCount = square;
double height = rowCount * childHeight;
double width = columnCount * childWidth;
Size size = new Size(width, height);
base.ArrangeOverride(size);
return size;
}
else
{
return new Size(300, 300);
}
}
然后我创建了一个扩展ItemsControl的自定义面板。这样我就可以将一组项目绑定到它。代码中没有任何内容,但这是我必须使用的风格。
<Style TargetType="{x:Type local:SquareItemsPanel}" BasedOn="{StaticResource {x:Type ItemsControl}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ItemsControl">
<Border BorderBrush="Black" BorderThickness="2" CornerRadius="4">
<Expander x:Name="exp" Header="View">
<local:SquareWrapPanel IsItemsHost="True"/>
</Expander>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>