WPF - Пользовательский размер панели для содержимого
Моя панель пытается сделать что-то похожее на UniformGrid, у нее есть свойство ColumnNumber, в дополнение к свойствам зависимостей ItemContainerWidth (40.0) и ItemContainerHeight (20.0).
Я хочу, чтобы размер моей панели соответствовал ее содержанию.
мой MesureOverride:
protected override Size MeasureOverride(Size constraint)
{
if (constraint.Width == double.PositiveInfinity || constraint.Height == double.PositiveInfinity)
return Size.Empty;
for (int i = 0; i < InternalChildren.Count; i++)
{
InternalChildren[i].Measure(new Size(ItemContainerWidth, ItemContainerHeight));
}
return constraint;
}
мой ArrangeOverride:
protected override Size ArrangeOverride(Size finalSize)
{
int currentColumn = 0;
int currentRow = 0 ;
for (int i = 0; i < InternalChildren.Count; i++)
{
UIElement child = InternalChildren[i];
if (currentColumn == ColumnCount)
{
currentColumn = 0;
currentRow++;
}
currentColumn++;
double top = currentRow * ItemContainerHeight;
double left = currentColumn * ItemContainerWidth;
child.Arrange(new Rect(left, top, ItemContainerWidth, ItemContainerHeight));
}
return finalSize;
}
ActualWidth и Height моей панели равны finalSize, я бы хотел, чтобы размер панели был таким, какой был возвращен из MeasureOvride (ограничение),
если я навязываю это, моя панель расположена по-разному на экране, я просто хочу, чтобы размер моей панели соответствовал ее содержимому, как WrapPanel или StackPanel,
с finalSize
с размером ограничения (100 100) для целей тестирования
мое использование панели: XAML:
<Grid>
<ItemsControl ItemsSource="{Binding Items, Mode=OneWay}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<uni:ScrollableUniformGrid ColumnCount="12" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="0,0,1,1">
<TextBlock Text="{Binding}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
2 ответа
Извините, я думаю, что я неправильно понял вас в первый раз.
Взгляните на это:
<Grid>
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<local:ScrollableUniformGrid HorizontalAlignment="Left" VerticalAlignment="Top" ColumnCount="3" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="0,0,1,1">
<TextBlock Text="{Binding}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
Вот так должен выглядеть ваш ArrangeOverride. MeasureOverride может остаться прежним.
protected override Size ArrangeOverride(Size finalSize)
{
int currentColumn = 0;
int currentRow = 0;
for (int i = 0; i < InternalChildren.Count; i++)
{
UIElement child = InternalChildren[i];
double top = currentRow * ItemContainerHeight;
double left = currentColumn * ItemContainerWidth;
if (currentColumn == ColumnCount)
{
currentColumn = 0;
currentRow++;
}
else
{
currentColumn++;
}
child.Arrange(new Rect(left, top, ItemContainerWidth, ItemContainerHeight));
}
return new Size((ColumnCount + 1) * ItemContainerWidth, (currentRow + 1) * ItemContainerHeight);
}
Посмотрите на это фото. Панель подходит для контента для меня.
Чтобы понять, что сказал dev hedgehod, что Grid - это родитель, растягивающий мою панель, я не думал об этом, подумал ли я, что ItemsControl был тем, кто устанавливает границы из моей панели.
Я закончил тем, что сделал следующее, я установил ширину и высоту на Авто в определении столбца и строки.
XAML:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ItemsControl ItemsSource="{Binding Items, Mode=OneWay}" Background="AliceBlue">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<uni:ScrollableUniformGrid ColumnCount="12" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="0,0,1,1">
<TextBlock Text="{Binding}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>