I am using the Infragistics XamDialogWindow to approximate an MDI window in WPF.
Basically I have a user control that I assign to the content of the window and then add the XamDialogWindow as a child of a Grid.
I then have two buttons which display the windows as either "Tile" or "Cascade".
The cascade works really well but I am having problems with the Tile method.
I get the available width and height using the "ActualWidth" and "ActualHeight" properties of the container.
I then calculate the number of rows and columns needed.
Next I iterate through the columns and I calculate how many rows there are in a column, (this means that if there are an odd number of windows such as 5 I will have two rows in column 0 and 3 in column 1).
The width of each window is worked out as "AvailableWidth / numColumns"
The height of each window is worked out as "AvailableHeight / WindowsForThisColumn"
I then iterate through the rows and calculate the top left coordinate of the window we are positioning as follows:
left = columnIndex * width
top = rowIndex * height
The Left, Top, Width and Height properties of the window are then set.
PROBLEM
The Left, Top, Width and Height properties seem to be calculated correctly so for example
This should give a nice grid of 4 windows with no margins filling all available space, however this is not the result.
The windows seem to be offset when displayed (see image below).
If I look at the Left, Top, Width and Height properties they all appear to be correct.
The weird thing is, if I click "Tile" a second time they will all appear correctly.
If I move a window after clicking tile the second time, they will appear correctly.
I have tried using a Canvas and setting the Canvas.Left and Top properties, A grid, stackpanel and wrappanel with the same results every time.
Can anyone help me? I think it may be a problem with how WPF measures sizes and locations at Render Time
var childrenToArrange = Children.Where(a => a.WindowState != Infragistics.Controls.Interactions.WindowState.Minimized).ToList();
var availableWidth = Panel.ActualWidth;
var availableHeight = Panel.ActualHeight;
if (Layout == MDILayout.TILE)
{
//get the number of rows and columns
int rows = (int)Math.Sqrt(childrenToArrange.Count);
int columns = childrenToArrange.Count / rows;
var index = 0;
var width = availableWidth / columns;
//iterate through the columns
for (int x = 0; x < columns; x++)
{
//get the number of windows for this column
var windowsForThisColumn = rows;
if (childrenToArrange.Count % columns > (columns - x - 1))
windowsForThisColumn++;
var height = availableHeight / windowsForThisColumn;
//iterate through the rows
for (int y = 0; y < windowsForThisColumn; y++)
{
//get the X and Y coordinates
var left = x * width;
var top = y * height;
//get the window
var mdiChild = childrenToArrange[index] as XamDialogWindow;
mdiChild.Margin = new Thickness(0);
mdiChild.Left = left;
mdiChild.Top = top;
mdiChild.Width = width;
mdiChild.Height = height;
index++;
}
}
}
I've reproduced the issue with your snippet. Please click the following hyperlink to the following forum post at Infragistics for further instructions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With