private static ResizableThumb GetRelationControl(ResizableThumb target)
        {
            // 1つ目の追加コントロールだった
            var targetModel = target.DataContext as DefinitionItemModel;

            if (string.IsNullOrEmpty(targetModel.RelationName))
            {
                return(null);
            }

            var items = Self.Children.OfType <ResizableThumb>().ToList();

            for (var i = items.Count - 1; i >= 0; i--)
            {
                var item         = items[i];
                var currentModel = item.DataContext as DefinitionItemModel;

                // 自分自身は飛ばす
                if (item == target)
                {
                    continue;
                }

                if (currentModel.DefinitionName == targetModel.RelationName)
                {
                    return(item);
                }
            }

            // 見つからなかった
            return(null);
        }
        private static ResizableThumb GetRelationFirstChildControl(ResizableThumb target)
        {
            var relationThumb = GetRelationControl(target);

            if (relationThumb is null)
            {
                return(null);
            }

            var relationModel = relationThumb.DataContext as DefinitionItemModel;

            if (relationModel is null)
            {
                return(null);
            }

            var items = Self.Children.OfType <ResizableThumb>().ToList();

            for (var i = 0; i < items.Count; i++)
            {
                var item         = items[i];
                var currentModel = item.DataContext as DefinitionItemModel;

                if (currentModel.RelationName == relationModel.DefinitionName)
                {
                    return(item);
                }
            }

            return(null);
        }
        private static void SetNewLocation(DefinitionItemModel model, ResizableThumb newThumb, ResizableThumb previousThumb)
        {
            // 1つ目
            if (previousThumb is null)
            {
                var pos = new Point(10, 10);
                Canvas.SetLeft(newThumb, pos.X);
                Canvas.SetTop(newThumb, pos.Y);
                return;
            }

            // 2つ目以降
            var previousModel = previousThumb.DataContext as DefinitionItemModel;

            if (previousModel.DefinitionName == model.RelationName)
            {
                // 右下
                var pos = GetRightBottomSideLocation(previousThumb);
                Canvas.SetLeft(newThumb, pos.X);
                Canvas.SetTop(newThumb, pos.Y);
                return;
            }
            else
            {
                // 位置関係によっては、1つ右ずれしてしまうバグの対応
                // 関係元のコントロールを基準として、その最初の関係するコントロールの真下とする
                previousThumb = GetRelationFirstChildControl(newThumb);

                // 真下
                var pos = GetMostBottomSideLocation(previousThumb);
                Canvas.SetLeft(newThumb, pos.X);
                Canvas.SetTop(newThumb, pos.Y);
                return;
            }
        }
        // 基準コントロールの右下位置

        private static Point GetRightBottomSideLocation(ResizableThumb previousThumb)
        {
            var newWidth  = previousThumb.DesiredSize.Width;
            var newHeight = previousThumb.DesiredSize.Height;

            var alpha = 40;
            var newX  = Canvas.GetLeft(previousThumb) + newWidth + alpha;
            var newY  = Canvas.GetTop(previousThumb) + newHeight + alpha;

            var result = new Point(newX, newY);

            return(result);
        }
        // 基準コントロールの真下、かつすべてのコントロールよりも真下の位置
        // あるツリー表示の2段目ツリーのイメージ

        private static Point GetMostBottomSideLocation(ResizableThumb previousThumb)
        {
            var newWidth  = previousThumb.DesiredSize.Width;
            var newHeight = previousThumb.DesiredSize.Height;

            var alpha = 40;
            var newX  = Canvas.GetLeft(previousThumb);
            var newY  = Canvas.GetTop(previousThumb) + newHeight + alpha;

            // 予測計算した位置に、すでに他のコントロールが配置されていないかチェック
            // 一部が重なり合う場合、重ならないように予測位置を修正して、再度全チェック
            var items = Self.Children.OfType <ResizableThumb>().ToList();
            var found = false;

            while (true)
            {
                // 初期化してチャレンジ、または再チャレンジ
                found = false;
                for (var i = 1; i < items.Count; i++)
                {
                    var item     = items[i];
                    var currentX = Canvas.GetLeft(item);
                    var currentY = Canvas.GetTop(item);

                    var currentWidth  = item.DesiredSize.Width;
                    var currentHeight = item.DesiredSize.Height;

                    if (newY < currentY + currentHeight + alpha)
                    {
                        found = true;
                        newY  = currentY + currentHeight + alpha;
                    }
                }

                // 既存配置しているコントロールリスト全てに重ならなかったので、この位置で決定
                if (!found)
                {
                    break;
                }

                // 見つかった場合は、1つ以上重なっていたことにより、予測位置を修正したので、
                // もう一度コントロールリスト全部と再チェック
            }

            var result = new Point(newX, newY);

            return(result);
        }
        private static void SetNewLocation(DefinitionItemModel model, ResizableThumb newThumb, ResizableThumb previousThumb)
        {
            // 1つ目
            if (previousThumb is null)
            {
                var pos = new Point(10, 10);
                Canvas.SetLeft(newThumb, pos.X);
                Canvas.SetTop(newThumb, pos.Y);
                return;
            }

            // 2つ目以降
            var previousModel = previousThumb.DataContext as DefinitionItemModel;

            if (string.IsNullOrEmpty(model.RelationName))
            {
                // 新しいプロジェクトの始まりの場合、1つ目の列に追加する
                previousThumb = Self.Children.OfType <ResizableThumb>().FirstOrDefault();

                // 真下
                var pos = GetMostBottomSideLocation(previousThumb);
                Canvas.SetLeft(newThumb, pos.X);
                Canvas.SetTop(newThumb, pos.Y);
                return;
            }
            else if (previousModel.DefinitionName == model.RelationName)
            {
                // 右隣
                var pos = GetRightSideLocation(previousThumb);
                Canvas.SetLeft(newThumb, pos.X);
                Canvas.SetTop(newThumb, pos.Y);
                return;
            }
            else
            {
                // 位置関係によっては、1つ右ずれしてしまうバグの対応
                // 関係元のコントロールを基準として、その最初の関係するコントロールの真下とする
                previousThumb = GetRelationFirstChildControl(newThumb);

                // 真下
                var pos = GetMostBottomSideLocation(previousThumb);
                Canvas.SetLeft(newThumb, pos.X);
                Canvas.SetTop(newThumb, pos.Y);
                return;
            }
        }
        private static ResizableThumb CreateControl(DefinitionItemModel model)
        {
            var thumbTemplate = Self.Resources["DefinitionMemberTemplate"] as ControlTemplate;
            var newThumb      = new ResizableThumb();

            newThumb.Template    = thumbTemplate;
            newThumb.DataContext = model;

            // いる?
            var newSize = new Size(50000, 50000);

            Self.Measure(newSize);

            newThumb.ApplyTemplate();
            newThumb.UpdateLayout();

            return(newThumb);
        }
        private static void AddArrow(ResizableThumb previousThumb, ResizableThumb newThumb)
        {
            var arrow1 = new Arrow {
                Stroke = Brushes.LightPink, Fill = Brushes.LightPink
            };

            Self.Children.Add(arrow1);

            previousThumb.EndLines.Add(arrow1);
            newThumb.StartLines.Add(arrow1);

            ResizableThumb.UpdateLineLocation(previousThumb);
            ResizableThumb.UpdateLineLocation(newThumb);

            // なぜか、最後の図形だけ、矢印線が左上の角を指してしまう不具合
            // → ActualWidth, ActualHeight が 0 だから。いったん画面表示させないとダメか?
            // → Measure メソッドを呼び出して、希望サイズを更新する。こちらで矢印線の位置を調整する
            var newSize = new Size(50000, 50000);

            Self.Measure(newSize);
            ResizableThumb.UpdateLineLocation(newThumb);
        }