protected override void OnLayout(LayoutEventArgs e) { base.OnLayout(e); var rect = ClientRectangle; // calculate dimension var dimension = Dimension; if (Dimension.Width > Dimension.Height) { var minSize = (MinimumCellSize.Width + CellSpace.Width) * Dimension.Width + CellSize.Width; if (rect.Height > rect.Width && Dimension.Width < minSize) { dimension = new Size(Dimension.Height, Dimension.Width); } } else if (Dimension.Width < Dimension.Height) { var minSize = (MinimumCellSize.Height + CellSpace.Height) * Dimension.Height + CellSize.Height; if (rect.Width > rect.Height && Dimension.Height < minSize) { dimension = new Size(Dimension.Height, Dimension.Width); } } ActualDimension = dimension; // calculate cell size var cellSize = new Size( (rect.Width - dimension.Width * CellSpace.Width) / dimension.Width, (rect.Height - dimension.Height * CellSpace.Height) / dimension.Height); cellSize.Width = Math.Min(CellSize.Width, Math.Max(MinimumCellSize.Width, cellSize.Width)); cellSize.Height = Math.Min(CellSize.Height, Math.Max(MinimumCellSize.Height, cellSize.Height)); ActualCellSize = cellSize; // calculate start location var startX = rect.X + (rect.Width - ((cellSize.Width + CellSpace.Width) * dimension.Width)) / 2; var startY = rect.Y + (rect.Height - ((cellSize.Height + CellSpace.Height) * dimension.Height)) / 2; startX = Math.Max(rect.X, startX) + CellSpace.Width / 2; startY = Math.Max(rect.Y, startY) + CellSpace.Height / 2; StartLocation = new Point(startX, startY); // calculate cell bounds int index = 0; foreach (var item in DisplayItems) { int x = index % dimension.Width; int y = index / dimension.Width; var cellBounds = new Rectangle( startX + x * (cellSize.Width + CellSpace.Width), startY + y * (cellSize.Height + CellSpace.Height), cellSize.Width, cellSize.Height); item.Bounds = PaintHelper.GetRectInBounds(cellBounds, CellSize.Width, CellSize.Height); index++; } }