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

с 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>
Другие вопросы по тегам