Перекрывающиеся элементы (элементы разного размера) в Masonry Itemscontrol WPF - PullRequest
0 голосов
/ 07 января 2019

Я пытаюсь реализовать панель инструментов с разными размерами виджетов. Пользователь может увеличивать или уменьшать каждый виджет следующим образом: enter image description here

Чтобы реализовать это, когда я искал в Google, познакомился с Masonry Itemscontrol (доступен в git hub https://github.com/Lizzaran/WPF-Masonry).

Он отлично работает для элементов разного размера, если пользователь не попытается увеличить разрыв. enter image description here

Вот основной код в 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);
}
...