Question

my panel attempts to do something similar to UniformGrid , it has a ColumnNumber property, in addition to ItemContainerWidth (40.0) and ItemContainerHeight (20.0) dependency properties.

I want my panel to size to it's content .

my 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;
 }

my 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;
    }

My panel's ActualWidth and Height Equal to finalSize , i would like the panel's size to be the one returned from MeasureOvride (constraint) ,

if i force this my panel is located differently on the screen , i just want my panel to size to it's content like WrapPanel or StackPanel,

with finalSize

with finalSize

with constraint size (100,100) for test purposes

with constraint size

my use of the panel : 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>
Was it helpful?

Solution

I am sorry I think I missunderstood you first time.

Take a look at this:

<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>

This is how your ArrangeOverride shall look like. MeasureOverride may stay the same.

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);
}

Take a look at this photo. The panel fits to content for me.

enter image description here

OTHER TIPS

to build appon what dev hedgehod said that the Grid is the parent stretching my panel , i didn't think about this has i thought that the ItemsControl was the one setting the bounds from my panel .

I ended up doing the following , i set Width and Height to Auto in a Column and Row definition.

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>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top