public class BlockPanel : Panel
{
//First measure all children and return available size of panel
protected override Size MeasureOverride(SizeavailableSize)
{
//Measure each child
foreach (FrameworkElement child in Children)
{
child.Measure(new Size(100,100));
}
//return the available size
return availableSize;
}
}
public class BlockPanel : Panel
{
//Second arrange all children and return final size of panel
protected override Size ArrangeOverride(Size finalSize)
{
//Get the collection of children
UIElementCollection mychildren = Children;
//Get the total number of children
int total = mychildren.Count;
//Calculate the number of 3x3 blocks needed
int blocks = (int)Math.Ceiling((double)total/9.00);
//Calculate how many 3x3 blocks fit on a row
int blocksInRow = (int)Math.Floor(finalSize.Width / 300); //assuming blocks of 9 element 300x300
//Arrange children
int i;
double maxWidth = 0;
double maxHeight = 0;
for (i = 0; i < total; i++)
{
//Find out which 3x3 block you are in
int block = FindBlock(i);
//Get (left, top) origin point for your 3x3 block
Point blockOrigin = GetOrigin(block, blocksInRow,new Size(300,300));
//Get (left, top) origin point for the element inside its 3x3 block
int numInBlock = i-9*block;
Point cellOrigin = GetOrigin(numInBlock, 3, newSize(100,100));
//Arrange child
//Get desired height and width. This will not be larger than 100x100 as set in MeasureOverride.
double dw = mychildren[i].DesiredSize.Width;
double dh = mychildren[i].DesiredSize.Height;
mychildren[i].Arrange(new Rect(blockOrigin.X + cellOrigin.X, blockOrigin.Y + cellOrigin.Y, dw, dh));
//Determine the maximum width and height needed for the panel
maxWidth = Math.Max(blockOrigin.X + 300, maxWidth);
maxHeight = Math.Max(blockOrigin.Y + 300, maxHeight);
}
//Return final size of the panel
return new Size(maxWidth,maxHeight);
}
}
- 어떤 3x3 블럭에 들어갈 것인가?
- 3x3 블럭안에 어떤 구역 숫자가 들어갈 것인가?
- 3x3 블럭의 Left,Top 코너 위치
- 3x3 블럭안 구역의 Left,Top 코너 위치.
- 각 객체의 DesiredSize.
- 우리가 child.Measure를 호출 했을 때, 우리는 자식들이 가능한 사이즈를 넘겨주는 것입니다. 자식들의 실제 사이즈를 설정해주는 것이 아닙니다.
- Measure 함수를 호출 한 뒤에 Layout System 은 Element의 DesiredSize를 결정할 것입니다. 다시 말해서 제가 말할 수 있는 것은 우리가 직접 DesiredSize를 설정할 수 있는 방법은 없다는 것입니다..
- 우리가 child.Arrange 를 호출 했을 때 우리는 child의 최종 사이즈(final size)를 설정하는 것이 아닙니다. 저는 잠시동안 이것이 child의 사이즈를 설정하는 것이라고 착각했지만 이것은 child를 포함할 경계 영역(bounding box)를 설정하는 것입니다. 그래서 만약 child가 경계영역보다 크다면 그것은 Clip 될 것이며 만약 child가 더 작다면 그것은 기본 정렬(역자주: 보통은 Center 정열)이나 당신이 정해준 정렬에 기반하여 경계 영역안에 위치될 것입니다. 이 Panel 경우에는 경계 영역이 child의 DesiredSize가 되도록 설정했습니다.