public void RemoveTableFromCanvas(TableModel tableModel)
        {
            try
            {
                TableObject[] tableObjectsArray = this.FindVisualControls(typeof(TableObject)).TryCast <TableObject>();

                TableObject tableObject = tableObjectsArray.FirstOrDefault(t => t.Table.TableName.ToLower() == tableModel.TableName.ToLower());

                if (tableObject == null)
                {
                    return;
                }


                this.Children.Remove(tableObject);

                if (this.RemoveTable != null)
                {
                    foreach (KeyValuePair <string, DatabaseRelation> relation in tableObject.ColumnRelationModel)
                    {
                        this.Children.Remove(relation.Value.LinePath[0]);

                        this.Children.Remove(relation.Value.LinePath[1]);

                        this.columnRelationModel.Remove(relation.Key);
                    }

                    this.RemoveTable?.Invoke(this, tableModel);

                    this.CanvasChanged?.Invoke(this, tableModel);

                    Integrity.RemoveTableMapping(tableModel);
                }
            }
            catch (Exception err)
            {
                MessageBox.Show(err.InnerExceptionMessage());
            }
        }
        public void RefreshTableRelations(TableModel tableModel)
        {
            TableObject[] tablesArray = this.FindVisualControls(typeof(TableObject)).TryCast <TableObject>();

            TableObject table = tablesArray.FirstOrDefault(t => t.Table.TableName == tableModel.TableName);

            if (table == null)
            {
                return;
            }

            KeyValuePair <string, DatabaseRelation>[] existingRelation = table.ColumnRelationModel.ToArray();

            foreach (KeyValuePair <string, DatabaseRelation> relation in existingRelation)
            {
                this.DatabaseRelation_Delete(relation.Value);

                if (this.columnRelationModel.ContainsKey(relation.Key))
                {
                    this.columnRelationModel.Remove(relation.Key);
                }
            }

            table.InitializeColumnRemations();

            UIElement[] tableControls = this.FindVisualControls(typeof(TableObject));

            foreach (KeyValuePair <string, DatabaseRelation> relation in table.ColumnRelationModel)
            {
                relation.Value.DatabaseRelationDelete += this.DatabaseRelation_Delete;

                this.columnRelationModel.Add(relation.Key, relation.Value);

                this.DrawRelation(table, tableControls, relation);
            }

            this.RedrawTableRelations(table);
        }
        private void TableObject_Remove(object sender, TableModel tableModel)
        {
            this.Children.Remove((TableObject)sender);

            if (this.RemoveTable != null)
            {
                TableObject tableObject = (TableObject)sender;

                foreach (KeyValuePair <string, DatabaseRelation> relation in tableObject.ColumnRelationModel)
                {
                    this.Children.Remove(relation.Value.LinePath[0]);

                    this.Children.Remove(relation.Value.LinePath[1]);

                    this.columnRelationModel.Remove(relation.Key);
                }

                this.RemoveTable?.Invoke(this, tableModel);

                this.CanvasChanged?.Invoke(this, tableModel);

                Integrity.RemoveTableMapping(tableModel);
            }
        }
        private Point[] CalculateIntersectionPoints(
            TableObject parentTable,
            TableObject childTable,
            string relationKey,
            ref double xOffset,
            ref double yOffset,
            ref Point parentPoint,
            ref Point childPoint)
        {
            Point[] result = new Point[2];

            int parentLinkIndex = parentTable.LinkedRelations.IndexOf(relationKey);

            int childLinkIndex = childTable.LinkedRelations.IndexOf(relationKey);

            string[] tablesArray = relationKey.Split(new string[] { "||" }, StringSplitOptions.RemoveEmptyEntries);

            int childKeyLinkCount = childTable.Table.Columns.Where(cc => cc.ForeignKeyTable == tablesArray[0] && cc.InPrimaryKey).Count();

            int childKeyCount = childTable.Table.Columns.Where(ck => ck.InPrimaryKey).Count();

            int parentKeyLinkCount = parentTable.Table.Columns.Where(pc => pc.InPrimaryKey).Count();

            bool isStrongKey = (childKeyLinkCount == 0 && childKeyLinkCount != childKeyCount) ? false : childKeyLinkCount == parentKeyLinkCount;

            double parentBottom = parentTable.DesiredSize.Height + parentPoint.Y;

            double childBottom = childTable.DesiredSize.Height + childPoint.Y;

            double parentWidth = parentTable.DesiredSize.Width + parentPoint.X;

            double childWidth = childTable.DesiredSize.Width + childPoint.X;

            TablePlacementEnum placement = ParentPlacementCalculator.CalculatePlacement(parentPoint, childPoint, parentWidth, childWidth, parentBottom, childBottom);

            if (childTable.Table.TableName == parentTable.Table.TableName)
            {
                #region TABLE REFERENCE IT SELF

                parentPoint.X += parentTable.DesiredSize.Width;

                parentPoint.Y += yOffset;

                childPoint.X += parentTable.DesiredSize.Width;

                childPoint.Y += (yOffset + 20);

                result[0] = new Point(parentPoint.X + xOffset, parentPoint.Y);

                result[1] = new Point(childPoint.X + xOffset, childPoint.Y);

                yOffset += 30;

                #endregion
            }
            else if (placement == TablePlacementEnum.ParentAtLeft)
            {
                #region PARENT IS LEFT OF CHILD

                parentPoint.X += parentTable.DesiredSize.Width;

                double parentHeightCentre = parentPoint.Y + (parentTable.DesiredSize.Height / 2);

                double childHeightCentre = childPoint.Y + (childTable.DesiredSize.Height / 2);

                parentPoint.Y = parentHeightCentre + (parentLinkIndex * 20);

                childPoint.Y = childHeightCentre + (childLinkIndex * 20);

                double xOffP = (parentPoint.X - childPoint.X) / 2;

                result[0] = new Point(parentPoint.X - xOffP, parentPoint.Y);

                result[1] = new Point(childPoint.X + xOffP, childPoint.Y);

                if (!isStrongKey)
                {
                    result = this.AddRightCrowsFeet(result, childPoint);
                }

                #endregion
            }
            else if (placement == TablePlacementEnum.ParentAtRight)
            {
                #region PARENT IS RIGHT OF CHILD

                childPoint.X += childTable.DesiredSize.Width;

                double parentHeightCentre = parentPoint.Y + (parentTable.DesiredSize.Height / 2);

                double childHeightCentre = childPoint.Y + (childTable.DesiredSize.Height / 2);

                parentPoint.Y = parentHeightCentre + (parentLinkIndex * 20);

                childPoint.Y = childHeightCentre + (childLinkIndex * 20);

                double xOffP = (parentPoint.X - childPoint.X) / 2;

                result[0] = new Point(parentPoint.X - xOffP, parentPoint.Y);

                result[1] = new Point(childPoint.X + xOffP, childPoint.Y);

                if (!isStrongKey)
                {
                    result = this.AddLeftCrowsFeet(result, childPoint);
                }

                #endregion
            }
            else if (placement == TablePlacementEnum.ParentAtBottom)
            {
                #region PARENT IS BOTTOM OF CHILD

                childPoint.Y += childTable.DesiredSize.Height;

                double parentWidthCentre = parentPoint.X + (parentTable.DesiredSize.Width / 2);

                double childWidthCentre = childPoint.X + (childTable.DesiredSize.Width / 2);

                parentPoint.X = parentWidthCentre + (parentLinkIndex * 20);

                childPoint.X = childWidthCentre + (childLinkIndex * 20);

                double yOffP = (parentPoint.Y - childPoint.Y) / 2;

                result[0] = new Point(parentPoint.X, parentPoint.Y - yOffP);

                result[1] = new Point(childPoint.X, childPoint.Y + yOffP);

                if (!isStrongKey)
                {
                    result = this.AddUpCrowsFeet(result, childPoint);
                }

                #endregion
            }
            else
            {
                #region PARENT IS TOP OF CHILD

                parentPoint.Y += parentTable.DesiredSize.Height;

                double parentWidthCentre = parentPoint.X + (parentTable.DesiredSize.Width / 2);

                double childWidthCentre = childPoint.X + (childTable.DesiredSize.Width / 2);

                parentPoint.X = parentWidthCentre + (parentLinkIndex * 20);

                childPoint.X = childWidthCentre + (childLinkIndex * 20);

                double yOffP = (parentPoint.Y - childPoint.Y) / 2;

                result[0] = new Point(parentPoint.X, parentPoint.Y - yOffP);

                result[1] = new Point(childPoint.X, childPoint.Y + yOffP);

                if (!isStrongKey)
                {
                    result = this.AddDownCrowsFeet(result, childPoint);
                }

                #endregion
            }

            return(result);
        }
        protected override void OnDrop(DragEventArgs e)
        {
            e.Handled = true;

            if (e.Data.GetDataPresent(DataFormats.StringFormat))
            {
                #region TABLE/RElATION DROPED FROM LEFT MENU

                object dataValue = e.Data.GetData(typeof(TableModel));

                this.CanvasChanged?.Invoke(this, dataValue);

                if (dataValue == null || dataValue.GetType() != typeof(TableModel))
                {
                    dataValue = e.Data.GetData(typeof(DatabaseRelation));

                    if (dataValue == null)
                    {
                        return;
                    }

                    this.AddNewRelation((DatabaseRelation)dataValue);

                    return;
                }

                TableModel table = (TableModel)dataValue;

                if (table.IsNewTable)
                {
                    table = new TableModel();

                    table.TableName = $"{this.NewTablePrefix}{this.Children.Count}";

                    TableEdit tableEdit = new TableEdit(table);

                    bool?result = tableEdit.ShowDialog();

                    if (!result.HasValue || !result.Value)
                    {
                        return;
                    }
                }

                if (!this.NewTablePrefix.IsNullEmptyOrWhiteSpace() && !table.TableName.StartsWith(this.NewTablePrefix))
                {
                    table.TableName = $"{this.NewTablePrefix}{table.TableName}";
                }

                table.CanvasLocation = e.GetPosition(this);

                this.CreateTableObject(table);

                this.TableAdded?.Invoke(this, table);

                #endregion
            }
            else if (e.Data.GetDataPresent(DataFormats.Serializable))
            {
                #region TABLE MOVE ON CANVAS

                object[] dataValues = (object[])e.Data.GetData(DataFormats.Serializable);

                if ((Type)dataValues[0] == typeof(TableObject))
                {
                    TableObject table = (TableObject)dataValues[1];

                    Point mousePos = e.GetPosition(this);

                    table.Location = mousePos;

                    table.StopDrag();

                    this.ResizeCanvas(mousePos, table.ActualHeight, table.ActualWidth);

                    this.RedrawTableRelations(table);
                }

                #endregion
            }

            base.OnDrop(e);
        }