Я пытаюсь реализовать панель инструментов с разными размерами виджетов. Пользователь может увеличивать или уменьшать каждый виджет следующим образом:
Чтобы реализовать это, когда я искал в Google, познакомился с Masonry Itemscontrol (доступен в git hub https://github.com/Lizzaran/WPF-Masonry).
Он отлично работает для элементов разного размера, если пользователь не попытается увеличить разрыв.
Вот основной код в Masonry Itemscontrol
private void UpdateUI1()
{
try
{
var matrix = new List<int[]> { new[] { 0, (int)this.ActualWidth, 0 } };
var hMax = 0;
var temp = this.Parent as ScrollViewer;
var allControls = VisualTreeHelper.GetChild(this, 0) as Visual;
var onlyRadLegend = allControls.ChildrenOfType<FrameworkElement>().ToList()
.Where(a => a.GetType().ToString() != null
&& a.GetType().ToString() == "DragAndDrop.Testing" || a.GetType().ToString() == "DragAndDrop.EmptyWidget").ToList();
foreach (var child in onlyRadLegend)
{
var element = child as FrameworkElement;
if (element != null)
{
var size = new[] { (int)element.ActualWidth + this.Spacing, (int)element.ActualHeight + this.Spacing };
var point = this.GetAttachPoint(matrix, size[0]);
matrix = this.UpdateAttachArea(matrix, point, size);
hMax = Math.Max(hMax, point[1] + size[1]);
this.UpdateAlignment(element);
var oldThickness = element.Margin;
if (Math.Abs(oldThickness.Left - point[0]) > 1 || Math.Abs(oldThickness.Top - point[1]) > 1)
{
this.SetPosition(element, point[1], point[0]);
}
}
}
}
catch (Exception ex)
{
}
}
protected virtual void SetPosition(FrameworkElement element, int newTop, int newLeft)
{
if (element != null)
{
element.Margin = new Thickness(newLeft, newTop, 0, 0);
}
}
private int[] GetAttachPoint(List<int[]> mtx, int width)
{
mtx.Sort(this.MatrixSortDepth);
var max = mtx[mtx.Count - 1][2];
for (int i = 0, length = mtx.Count; i < length; i++)
{
if (mtx[i][2] >= max)
{
break;
}
if (mtx[i][1] - mtx[i][0] >= width)
{
return new[] { mtx[i][0], mtx[i][2] };
}
}
return new[] { 0, max };
}
private List<int[]> UpdateAttachArea(List<int[]> mtx, int[] point, int[] size)
{
mtx.Sort(this.MatrixSortDepth);
int[] cell = { point[0], point[0] + size[0], point[1] + size[1] };
for (int i = 0, length = mtx.Count; i < length; i++)
{
if (mtx.Count - 1 >= i)
{
if (cell[0] <= mtx[i][0] && mtx[i][1] <= cell[1])
{
mtx.RemoveAt(i);
}
else
{
mtx[i] = this.MatrixTrimWidth(mtx[i], cell);
}
}
}
return this.MatrixJoin(mtx, cell);
}