using CloudBuilder;
using CloudBuilder.Core.DependencyInjection.Form;
using CloudBuilder.Core.Service;
using CloudBuilder.Core.Utility;
using CloudBuilder.Gui;
using CloudBuilder.Gui.DependencyInjection;
using CloudBuilder.Request.Security;
using CloudBuilder.Security;
using CloudBuilder.Security.Entity;
using CloudBuilder.Security.SearchCriteria;
using CloudBuilder.Util;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;

namespace Krypton.Toolkit
{
    public static class KryptonDataGridViewExtensions
    {
        public static void Set(this KryptonDataGridView kryptonDataGridView,
            BindingContextCustomAttribute bindingContext)
        {
            GetProvider().SetCustomAttribute(kryptonDataGridView, bindingContext);
        }

        public static void Set(this KryptonDataGridView kryptonDataGridView, List<dynamic> dataSource,
            DataTable dataTableSource,
            DataTable deleteDataTableSource
            )
        {
            GetProvider().SetCustomAttribute(kryptonDataGridView, dataSource, dataTableSource, deleteDataTableSource);
        }

        #region 数据操作


        public static void DataSourceSorted(this KryptonDataGridView kryptonDataGridView,
            DataGridViewColumn cloumn, string columnName, ListSortDirection sortDirection)
        {
            DataTable dataTableSource = GetProvider().GetCustomAttribute(kryptonDataGridView).DataTableSource;

            if (dataTableSource == null || dataTableSource.Columns.Count == 0) return;
            dataTableSource.DefaultView.Sort = columnName;
            kryptonDataGridView.Sort(cloumn, sortDirection);
        }

        public static void SetDataSource<T>(this KryptonDataGridView kryptonDataGridView,
            List<T> ds)
        {
            DataTable dataTableSource = GetProvider().GetCustomAttribute(kryptonDataGridView).DataTableSource;
            DataTable deleteDataTableSource = GetProvider().GetCustomAttribute(kryptonDataGridView).DeleteDataTableSource;
            if (ds == null)
            {
                kryptonDataGridView.DataSource = null;
                kryptonDataGridView.Refresh();
                dataTableSource = new DataTable();
                deleteDataTableSource = new DataTable();
                Set(kryptonDataGridView, null!, dataTableSource, deleteDataTableSource);
                return;
            }
            else
            {

            }

            dataTableSource = DataTableConvertor.ToDataTable<T>(ds);

            kryptonDataGridView.DataSource = dataTableSource;
            kryptonDataGridView.Refresh();
            dataTableSource.AcceptChanges();

            deleteDataTableSource = dataTableSource.Clone();

            IEnumerable<dynamic> dynamicEnumerable = ds.Cast<dynamic>();

            Set(kryptonDataGridView, dynamicEnumerable.ToList(), dataTableSource, deleteDataTableSource);
        }

        public static void Clear(this KryptonDataGridView kryptonDataGridView)
        {
            DataTable dataTableSource = GetProvider().GetCustomAttribute(kryptonDataGridView).DataTableSource;
            DataTable deleteDataTableSource = GetProvider().GetCustomAttribute(kryptonDataGridView).DeleteDataTableSource;

            kryptonDataGridView.DataSource = null;
            kryptonDataGridView.Refresh();
            dataTableSource = new DataTable();
            deleteDataTableSource = new DataTable();
            Set(kryptonDataGridView, null!, dataTableSource, deleteDataTableSource);
        }

        public static void SetDataSource<T>(this KryptonDataGridView kryptonDataGridView,
            T[] ds)
        {
            DataTable dataTableSource = GetProvider().GetCustomAttribute(kryptonDataGridView).DataTableSource;
            DataTable deleteDataTableSource = GetProvider().GetCustomAttribute(kryptonDataGridView).DeleteDataTableSource;



            if (ds == null)
            {
                kryptonDataGridView.DataSource = null;
                dataTableSource = new DataTable();
                deleteDataTableSource = new DataTable();
                Set(kryptonDataGridView, null!, dataTableSource, deleteDataTableSource);
                return;
            }

            //首先將entity轉為datatable
            dataTableSource = DataTableConvertor.ToDataTable<T>(ds);
            dataTableSource.AcceptChanges();
            deleteDataTableSource = dataTableSource.Clone();

            IEnumerable<dynamic> dynamicEnumerable = ds.Cast<dynamic>();

            Set(kryptonDataGridView, dynamicEnumerable.ToList(), dataTableSource, deleteDataTableSource);

            kryptonDataGridView.DataSource = dataTableSource;
            kryptonDataGridView.Refresh();
        }

        public static void SetDataSourceCustomAttributee<T>(this KryptonDataGridView kryptonDataGridView,
            T[] ds)
        {
            if (ds == null)
            {
                kryptonDataGridView.DataSource = null;
                GetProvider().GetCustomAttribute(kryptonDataGridView).DataSource = default!;
            }
            else
            {
                IEnumerable<dynamic> dynamicEnumerable = ds.Cast<dynamic>();

                GetProvider().GetCustomAttribute(kryptonDataGridView).DataSource = dynamicEnumerable.ToList();
            }
        }

        public static void SetDataSourceCustomAttributee<T>(this KryptonDataGridView kryptonDataGridView,
      List<T> ds)
        {
            if (ds == null)
            {
                kryptonDataGridView.DataSource = null;
                GetProvider().GetCustomAttribute(kryptonDataGridView).DataSource = default!;
            }
            else
            {
                IEnumerable<dynamic> dynamicEnumerable = ds.Cast<dynamic>();

                GetProvider().GetCustomAttribute(kryptonDataGridView).DataSource = dynamicEnumerable.ToList();
            }
        }

        public static T[] GetAddRows<T>(this KryptonDataGridView kryptonDataGridView) where T : new()
        {
            return GetRows<T>(kryptonDataGridView, DataRowState.Added);
        }

        private static T[] GetRows<T>(this KryptonDataGridView kryptonDataGridView, DataRowState drs) where T : new()
        {
            DataTable dataTableSource = GetProvider().GetCustomAttribute(kryptonDataGridView).DataTableSource;

            if (dataTableSource == null || dataTableSource.Rows.Count == 0) return null!;

            DataTable dt = dataTableSource.Clone();
            foreach (DataRowView drv in dataTableSource.DefaultView)
            {
                if (drv.Row.RowState != drs || drv.Row.RowState == DataRowState.Deleted) continue;

                //drv.Row.AcceptChanges();
                dt.ImportRow(drv.Row);
            }

            if (dt.Rows.Count == 0) return null;

            List<T> l = DataTableConvertor.ConvertToList<T>(dt);

            return l.ToArray();
        }

        public static void AddRow<T>(this KryptonDataGridView kryptonDataGridView, T rows) where T : new()
        {
            AddRow<T>(kryptonDataGridView, new T[] { rows });
        }

        public static void AddRow<T>(this KryptonDataGridView kryptonDataGridView, List<T> rows) where T : new()
        {
            AddRow<T>(kryptonDataGridView, rows.ToArray());
        }

        public static void UpdateRow<T>(this KryptonDataGridView kryptonDataGridView, T d, int rowIndex)
        {
            DataTable dataTableSource = GetProvider().GetCustomAttribute(kryptonDataGridView).DataTableSource;
            DataTable deleteDataTableSource = GetProvider().GetCustomAttribute(kryptonDataGridView).DeleteDataTableSource;

            if (d == null) return;
            if (dataTableSource == null || dataTableSource.Rows.Count == 0) return;

            GetProvider().GetCustomAttribute(kryptonDataGridView).DataSource[rowIndex] = d;

            int i = 0;
            foreach (DataRowView drv in dataTableSource.DefaultView)
            {
                if (drv.Row.RowState == DataRowState.Deleted)
                {
                    rowIndex = rowIndex + 1;
                    i++;
                    continue;
                }

                if (i != rowIndex)
                {
                    i++;
                    continue;
                }

                DataRow dr = drv.Row;

                PropertyInfo[] pi = typeof(T).GetProperties();

                foreach (PropertyInfo p in pi)
                {
                    foreach (DataColumn dc in dataTableSource.Columns)
                    {
                        if (p.Name != dc.ColumnName) continue;

                        dr[dc] = p.GetValue(d, null) ?? DBNull.Value;

                        break;
                    }
                }

                kryptonDataGridView.DataSource = dataTableSource;
                kryptonDataGridView.Refresh();
                Set(kryptonDataGridView, GetProvider().GetCustomAttribute(kryptonDataGridView).DataSource, dataTableSource, deleteDataTableSource);
                return;
            }
        }

        public static void DeleteRow(this KryptonDataGridView kryptonDataGridView, int rowIndex)
        {
            DataTable dataTableSource = GetProvider().GetCustomAttribute(kryptonDataGridView).DataTableSource;
            DataTable deleteDataTableSource = GetProvider().GetCustomAttribute(kryptonDataGridView).DeleteDataTableSource;

            GetProvider().GetCustomAttribute(kryptonDataGridView).DataSource.RemoveAt(rowIndex);

            int i = 0;
            foreach (DataRowView drv in dataTableSource.DefaultView)
            {
                if (drv.Row.RowState == DataRowState.Deleted)
                {
                    rowIndex = rowIndex + 1;

                    i++;
                    continue;
                }

                if (i != rowIndex)
                {
                    i++;
                    continue;
                }

                if (drv.Row.RowState != DataRowState.Added)
                    deleteDataTableSource.ImportRow(drv.Row);

                dataTableSource.DefaultView.Delete(rowIndex);

                i++;
                break;
            }

            Set(kryptonDataGridView, GetProvider().GetCustomAttribute(kryptonDataGridView).DataSource, dataTableSource, deleteDataTableSource);
        }

        public static void DeleteRows(this KryptonDataGridView kryptonDataGridView, DataGridViewSelectedRowCollection drc)
        {
            foreach (DataGridViewRow dr in drc)
            {
                DeleteRow(kryptonDataGridView, dr.Index);
            }
        }

        public static void DeleteRows(this KryptonDataGridView kryptonDataGridView, DataGridViewSelectedCellCollection drc)
        {
            List<int> rows = new List<int>();

            foreach (DataGridViewCell dr in drc)
            {
                if (rows.Contains(dr.RowIndex)) continue;

                rows.Add(dr.RowIndex);
            }
            //删除要从最大的行先删除，不然数据会发生变化，大的行数，接下来就没有对应的了
            foreach (int i in rows.OrderByDescending(x => x).ToArray())
            {
                DeleteRow(kryptonDataGridView, i);
            }
        }

        public static void AddRow<T>(this KryptonDataGridView kryptonDataGridView, T[] rows) where T : new()
        {
            DataTable dataTableSource = GetProvider().GetCustomAttribute(kryptonDataGridView).DataTableSource;
            DataTable deleteDataTableSource = GetProvider().GetCustomAttribute(kryptonDataGridView).DeleteDataTableSource;

            if (rows != null && rows.Length > 0)
            {
                foreach (var row in rows)
                {
                    if (GetProvider().GetCustomAttribute(kryptonDataGridView).DataSource == null)
                        GetProvider().GetCustomAttribute(kryptonDataGridView).DataSource = new List<dynamic>();

                    GetProvider().GetCustomAttribute(kryptonDataGridView).DataSource.Add(row);
                }
            }

            DataTable dt = DataTableConvertor.ToDataTable<T>(rows);

            if (dataTableSource == null || dataTableSource.Columns.Count == 0)
            {
                dataTableSource = dt.Clone();

                kryptonDataGridView.DataSource = dataTableSource;

                dataTableSource.AcceptChanges();

                deleteDataTableSource = dataTableSource.Clone();
            }

            foreach (DataRow dc in dt.Rows)
            {
                dataTableSource.ImportRow(dc);
                kryptonDataGridView.DataSource = dataTableSource;
                kryptonDataGridView.Refresh();
            }

            Set(kryptonDataGridView, GetProvider().GetCustomAttribute(kryptonDataGridView).DataSource, dataTableSource, deleteDataTableSource);
        }

        public static T[] GetDeleteRows<T>(this KryptonDataGridView kryptonDataGridView) where T : new()
        {
            DataTable dataTableSource = GetProvider().GetCustomAttribute(kryptonDataGridView).DataTableSource;
            DataTable deleteDataTableSource = GetProvider().GetCustomAttribute(kryptonDataGridView).DeleteDataTableSource;

            if (deleteDataTableSource.Rows.Count == 0) return null;

            List<T> l = DataTableConvertor.ConvertToList<T>(deleteDataTableSource);

            return l.ToArray();
        }

        public static T[] GetUpdateRows<T>(this KryptonDataGridView kryptonDataGridView) where T : new()
        {
            return GetRows<T>(kryptonDataGridView, DataRowState.Modified);
        }

        public static T[] GetUnchangedRows<T>(this KryptonDataGridView kryptonDataGridView) where T : new()
        {
            return GetRows<T>(kryptonDataGridView, DataRowState.Unchanged);
        }

        public static T[] GetAllRows<T>(this KryptonDataGridView kryptonDataGridView) where T : new()
        {
            DataTable dataTableSource = GetProvider().GetCustomAttribute(kryptonDataGridView).DataTableSource;
            DataTable deleteDataTableSource = GetProvider().GetCustomAttribute(kryptonDataGridView).DeleteDataTableSource;

            if (dataTableSource.Rows.Count == 0) return null;


            DataTable dt = dataTableSource.Clone();

            foreach (DataRowView drv in dataTableSource.DefaultView)
            {
                if (drv.Row.RowState == DataRowState.Deleted) continue;

                //drv.Row.AcceptChanges();
                dt.ImportRow(drv.Row);
            }

            if (dt.Rows.Count == 0) return null;

            List<T> l = DataTableConvertor.ConvertToList<T>(dt);

            return l.ToArray();
        }

        public static T[] GetDataSourceCustomAttribute<T>(this KryptonDataGridView kryptonDataGridView) where T : new()
        {
            if (GetProvider().GetCustomAttribute(kryptonDataGridView).DataSource == null) return null!;

            IEnumerable<T> dynamicEnumerable = GetProvider().GetCustomAttribute(kryptonDataGridView).DataSource.Cast<T>();
            return dynamicEnumerable.ToArray();
        }

        public static T GetRowData<T>(this KryptonDataGridView kryptonDataGridView, int rowIndex) where T : new()
        {
            DataTable dataTableSource = GetProvider().GetCustomAttribute(kryptonDataGridView).DataTableSource;

            if (dataTableSource == null || dataTableSource.Rows.Count == 0) return default!;

            int i = 0;
            foreach (DataRowView drv in dataTableSource.DefaultView)
            {
                if (drv.Row.RowState == DataRowState.Deleted)
                {
                    rowIndex = rowIndex + 1;
                    i++;
                    continue;
                }

                if (i != rowIndex)
                {
                    i++;
                    continue;
                }
                DataTable dt = dataTableSource.Clone();
                //drv.Row.AcceptChanges();
                dt.ImportRow(drv.Row);

                List<T> l = DataTableConvertor.ConvertToList<T>(dt);

                i++;
                return l[0];
            }

            return default(T);
        }

        public static T[] GetSelectedCellsData<T>(this KryptonDataGridView kryptonDataGridView) where T : new()
        {
            DataTable dataTableSource = GetProvider().GetCustomAttribute(kryptonDataGridView).DataTableSource;

            if (dataTableSource == null || dataTableSource.Rows.Count == 0) return null!;

            List<int> rows = new List<int>();

            foreach (DataGridViewCell dr in kryptonDataGridView.SelectedCells)
            {
                if (rows.Contains(dr.RowIndex)) continue;

                rows.Add(dr.RowIndex);
            }

            if (rows.Count == 0) return null;

            return GetRowsData<T>(kryptonDataGridView, rows.ToArray());
        }

        public static T[] GetSelectedRowsData<T>(this KryptonDataGridView kryptonDataGridView) where T : new()
        {
            DataTable dataTableSource = GetProvider().GetCustomAttribute(kryptonDataGridView).DataTableSource;
            if (dataTableSource == null || dataTableSource.Rows.Count == 0) return null!;

            List<int> rows = new List<int>();

            foreach (DataGridViewRow dr in kryptonDataGridView.SelectedRows)
            {
                if (rows.Contains(dr.Index)) continue;

                rows.Add(dr.Index);
            }

            if (rows.Count == 0) return null;

            return GetRowsData<T>(kryptonDataGridView, rows.ToArray());
        }

        public static T[] GetRowsData<T>(this KryptonDataGridView kryptonDataGridView, int[] rows) where T : new()
        {
            DataTable dataTableSource = GetProvider().GetCustomAttribute(kryptonDataGridView).DataTableSource;
            if (dataTableSource == null) return null;

            DataTable dt = dataTableSource.Clone();

            foreach (int j in rows)
            {
                int rowIndex = j;

                int i = 0;
                foreach (DataRowView drv in dataTableSource.DefaultView)
                {
                    if (drv.Row.RowState == DataRowState.Deleted)
                    {
                        rowIndex = rowIndex + 1;
                        i++;
                        continue;
                    }

                    if (i != rowIndex)
                    {
                        i++;
                        continue;
                    }
                    //drv.Row.AcceptChanges();
                    dt.ImportRow(drv.Row);
                    break;
                }
            }

            List<T> l = DataTableConvertor.ConvertToList<T>(dt);

            return l.ToArray();
        }

        public static int[] GetRowIndexs(this KryptonDataGridView kryptonDataGridView, DataGridViewSelectedCellCollection selectedCells)
        {
            List<int> rowIndexs = new List<int>();

            foreach (DataGridViewCell cell in selectedCells)
            {
                if (!rowIndexs.Contains(cell.RowIndex)) rowIndexs.Add(cell.RowIndex);
            }

            return rowIndexs.ToArray();
        }

        public static ExDataGridViewSnapshot TakeSnapshot(this KryptonDataGridView kryptonDataGridView)
        {
            DataTable dataTableSource = GetProvider().GetCustomAttribute(kryptonDataGridView).DataTableSource;
            DataTable deleteDataTableSource = GetProvider().GetCustomAttribute(kryptonDataGridView).DeleteDataTableSource;

            if (dataTableSource == null || GetProvider().GetCustomAttribute(kryptonDataGridView).DataSource == null) return null;

            return new ExDataGridViewSnapshot()
            {
                DataSource = GetProvider().GetCustomAttribute(kryptonDataGridView).DataSource,
                DataTableSource = dataTableSource.Copy(),
                DeleteDataTableSource = deleteDataTableSource.Copy()
            };
        }

        public static void SetSnapshot(this KryptonDataGridView kryptonDataGridView, ExDataGridViewSnapshot snapshot)
        {
            DataTable dataTableSource = GetProvider().GetCustomAttribute(kryptonDataGridView).DataTableSource;
            DataTable deleteDataTableSource = GetProvider().GetCustomAttribute(kryptonDataGridView).DeleteDataTableSource;

            if (snapshot == null) return;

            kryptonDataGridView.DataSource = dataTableSource = snapshot.DataTableSource;
            kryptonDataGridView.Refresh();
            deleteDataTableSource = snapshot.DeleteDataTableSource;

            Set(kryptonDataGridView, snapshot.DataSource, dataTableSource, deleteDataTableSource);
        }

        public static void SetColumnDataSource<T>(this KryptonDataGridView kryptonDataGridView, KryptonDataGridViewComboBoxColumn comboxCol, List<T> ds, string displayMember, string valueMember, bool blankOption)
        {
            if (ds == null)
            {
                comboxCol.DataSource = null;

                return;
            }
            DataTable colDtbll = null;

            colDtbll = DataTableConvertor.ToDataTable<T>(ds, blankOption);

            comboxCol.DataSource = colDtbll;
            comboxCol.DisplayMember = displayMember;
            comboxCol.ValueMember = valueMember;
        }

        public static void SetColumnDataSource<T>(this KryptonDataGridView kryptonDataGridView, KryptonDataGridViewComboBoxColumn comboxCol, T[] ds, string displayMember, string valueMember, bool blankOption)
        {
            if (ds == null)
            {
                comboxCol.DataSource = null;
                return;
            }

            SetColumnDataSource(kryptonDataGridView, comboxCol, ds.ToList(), displayMember, valueMember, blankOption);
        }

        public static void SetColumnDataSource(this KryptonDataGridView kryptonDataGridView, KryptonDataGridViewComboBoxColumn comboxCol, TableName<string>[] values, bool blankOption)
        {
            SetColumnDataSource<TableName<string>>(kryptonDataGridView, comboxCol, values, TableName<string>.DISPLAY_NAME, TableName<string>.VALUE, blankOption);
        }


        public static void SetColumnDataSource<T>(this KryptonDataGridView kryptonDataGridView, DataGridViewComboBoxColumn comboxCol, List<T> ds, string displayMember, string valueMember, bool blankOption)
        {
            if (ds == null)
            {
                comboxCol.DataSource = null;

                return;
            }
            DataTable colDtbll = null;

            colDtbll = DataTableConvertor.ToDataTable<T>(ds, blankOption);

            comboxCol.DataSource = colDtbll;
            comboxCol.DisplayMember = displayMember;
            comboxCol.ValueMember = valueMember;
        }

        public static void SetColumnDataSource<T>(this KryptonDataGridView kryptonDataGridView, DataGridViewComboBoxColumn comboxCol, T[] ds, string displayMember, string valueMember, bool blankOption)
        {
            if (ds == null)
            {
                comboxCol.DataSource = null;
                return;
            }

            SetColumnDataSource(kryptonDataGridView, comboxCol, ds.ToList(), displayMember, valueMember, blankOption);
        }

        public static void SetColumnDataSource(this KryptonDataGridView kryptonDataGridView, DataGridViewComboBoxColumn comboxCol, TableName<string>[] values, bool blankOption)
        {
            SetColumnDataSource<TableName<string>>(kryptonDataGridView, comboxCol, values, TableName<string>.DISPLAY_NAME, TableName<string>.VALUE, blankOption);
        }

        #endregion

        public static BindingContextCustomAttribute GetCustomAttribute(this KryptonDataGridView kryptonDataGridView)
        {
            return GetProvider().GetCustomAttribute(kryptonDataGridView);
        }


        public static void InitColumn(this KryptonDataGridView kryptonDataGridView, bool isSort, bool showRowNumber)
        {
            kryptonDataGridView.AutoGenerateColumns = false;

            foreach (DataGridViewColumn column in kryptonDataGridView.Columns)
            {
                column.SortMode = isSort ? DataGridViewColumnSortMode.Automatic : DataGridViewColumnSortMode.NotSortable;
            }

            kryptonDataGridView.LoadUserPreference();
            kryptonDataGridView.EditMode = DataGridViewEditMode.EditOnEnter;

            if (showRowNumber)
                kryptonDataGridView.RowPostPaint += (sender, e) =>
                {
                    // 绘制行号
                    if (e.RowIndex >= 0)
                    {
                        Rectangle bounds = new Rectangle(
                            e.RowBounds.Left,
                            e.RowBounds.Top,
                            kryptonDataGridView.RowHeadersWidth,
                            e.RowBounds.Height);

                        TextRenderer.DrawText(e.Graphics,
                            (e.RowIndex + 1).ToString(),
                            kryptonDataGridView.RowHeadersDefaultCellStyle.Font,
                            bounds,
                            kryptonDataGridView.RowHeadersDefaultCellStyle.ForeColor,
                            TextFormatFlags.Right | TextFormatFlags.VerticalCenter);
                    }

                    // 绘制总数（只在第一行绘制一次）
                    if (e.RowIndex == 0)
                    {
                        var headerBounds = kryptonDataGridView.GetCellDisplayRectangle(-1, -1, true);
                        if (headerBounds.Width > 0)
                        {
                            TextRenderer.DrawText(e.Graphics,
                                $"{kryptonDataGridView.RowCount}",
                                kryptonDataGridView.RowHeadersDefaultCellStyle.Font,
                                headerBounds,
                                Color.DarkBlue,
                                TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);
                        }
                    }
                };

            ContextMenuStrip contextMenuStrip;
            ToolStripMenuItem adjustColumnsToolStripMenuItem;
            contextMenuStrip = new ContextMenuStrip();
            adjustColumnsToolStripMenuItem = new ToolStripMenuItem();

            contextMenuStrip.SuspendLayout();

            contextMenuStrip.Items.AddRange(new ToolStripItem[] { adjustColumnsToolStripMenuItem });

            contextMenuStrip.Name = "contextMenuStrip";


            Set(kryptonDataGridView, null!, null, null);

            // 
            // adjustColumnsToolStripMenuItem
            // 

            adjustColumnsToolStripMenuItem.Name = kryptonDataGridView.Name + DateTime.Now.ToString("yyyyHHddhhmmss");// "adjustColumnsToolStripMenuItem";
            adjustColumnsToolStripMenuItem.Text = "调整列属性";
            adjustColumnsToolStripMenuItem.Tag = kryptonDataGridView;
            adjustColumnsToolStripMenuItem.Click += new System.EventHandler(adjustColumnsToolStripMenuItem_Click);

            kryptonDataGridView.TopLeftHeaderCell.ContextMenuStrip = contextMenuStrip;
            foreach (DataGridViewColumn column in kryptonDataGridView.Columns)
            {
                column.HeaderCell.ContextMenuStrip = contextMenuStrip;
            }

            //kryptonDataGridView.ContextMenuStrip = contextMenuStrip;

            contextMenuStrip.ResumeLayout(false);
        }

        public static void adjustColumnsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            KryptonDataGridViewColumnSetDialog f = new KryptonDataGridViewColumnSetDialog((KryptonDataGridView)((ToolStripMenuItem)sender).Tag);

            f.ShowDialog();
        }

        public static string GetFormName(this KryptonDataGridView kryptonDataGridView, Control control)
        {
            //弹出的对话框时会为空
            if (control == null) return string.Empty;
            if (control.Parent is AbstractPage || control.Parent is KryptonForm) return control.Parent.ToString();
            else return kryptonDataGridView.GetFormName(control.Parent);
        }

        //加載用戶配置文件
        public static void LoadUserPreference(this KryptonDataGridView kryptonDataGridView)
        {
            try
            {
                SecurityUserPreferenceEntity load = null!;


                SecurityUserPreferenceRequest request = ServiceHelper.GetTypeService<SecurityUserPreferenceRequest>();
                SecurityUserPreferenceEntityKey key = new SecurityUserPreferenceEntityKey();
                key.Username = ApplicationServiceContext.Context.Requestor;

                key.PreferenceKey = kryptonDataGridView.GetFormName(kryptonDataGridView) + "." + kryptonDataGridView.Name;

                load = request.FindByKey(key);

                if (load == null) return;

                ExDataGridViewInfo info = DeserializeHelper<ExDataGridViewInfo>.Deserialize(load.Preference);

                Dictionary<string, string[]> dic = new Dictionary<string, string[]>();

                int i = 0;

                DataGridViewColumnsInfo cf;

                foreach (DataGridViewColumnsInfo column in info.ColumnsInfo)
                {
                    kryptonDataGridView.Columns[i].Frozen = false;

                    dic.Add(column.Name, new string[] { column.DisplayIndex, column.Width, column.Visiable });

                    i++;
                }

                kryptonDataGridView.LoadGridView(dic);

                if (!string.IsNullOrEmpty(info.FrozenName)) kryptonDataGridView.Columns[info.FrozenName].Frozen = true;
            }
            catch (Exception ex)
            {
                ShowMessageBox.ShowError(ex.Message);
            }
        }

        /// <summary>
        /// 保存列的设置，按顺序为：列名,显示顺序,列宽,是否可见(True,false字符串)
        /// 自己需要将返回的内容持久化,通畅持久化需要再封装一次，增加用户及使用位置的标识，这样不同用户就可以有独立的配置
        /// </summary>
        /// <returns>返回的列名为dictionary[0]，显示顺序(dictionary[0])[0],列宽(dictionary[0])[1]，是否可见(dictionary[0])[2]</returns>
        public static Dictionary<string, string[]> SaveGridView(this KryptonDataGridView kryptonDataGridView)
        {
            Dictionary<string, string[]> dict = new Dictionary<string, string[]>();

            for (int i = 0; i < kryptonDataGridView.Columns.Count; i++)
            {
                foreach (DataGridViewColumn col in kryptonDataGridView.Columns)
                {
                    if (col.DisplayIndex == i)
                    {
                        string[] value = { col.DisplayIndex.ToString(), col.Width.ToString(), col.Visible.ToString() };
                        dict.Add(col.Name, value);
                    }
                }
            }
            return dict;
        }

        /// <summary>
        /// 列宽的加载，从传入的字典内加载用户传入的列信息
        /// 传入的内容应该按照显示顺序由小到大进行排序了
        /// 将持久化的列信息加载，一般应包含当前用户及控件使用位置信息
        /// </summary>
        /// <param name="dict">Dictionary<列名,{显示顺序,列宽,是否可见(True,false字符串)}></param>
        public static void LoadGridView(this KryptonDataGridView kryptonDataGridView, Dictionary<string, string[]> dict)
        {
            if (dict.Count <= 0) return;

            try
            {
                foreach (string dic in dict.Keys)
                {
                    if (kryptonDataGridView.Columns.Contains(dic))
                    {
                        DataGridViewColumn column = kryptonDataGridView.Columns[dic];
                        column.DisplayIndex = Convert.ToInt32(dict[dic][0]);
                        column.Visible = Convert.ToBoolean(dict[dic][2]);
                        if (column.Visible)
                        {
                            column.Width = Convert.ToInt32(dict[dic][1]) > 20 ? Convert.ToInt32(dict[dic][1]) : 120; //小于20则自动调整为120.
                        }
                    }
                }
            }
            catch (Exception e)
            {

                throw e;
            }

        }

        private static BindingContextAttributeProvider GetProvider()
        {
            return ServiceHelper.GetService<BindingContextAttributeProvider>() ??
        throw new InvalidOperationException("BindingContextAttributeProvider is not registered in the service GetProvider().");
        }

        public static TemplateHeader[] GetTemplateHeaders(this KryptonDataGridView kryptonDataGridView)
        {
            List<TemplateHeader> headers = new List<TemplateHeader>();
            foreach (DataGridViewColumn column in kryptonDataGridView.Columns)
            {
                TemplateHeader header = new TemplateHeader();
                header.BindingName = column.DataPropertyName;
                header.DisplayName = column.HeaderText;
                header.Format = column.DefaultCellStyle.Format;
                if (!column.Visible) continue;
                header.Width = column.Width / 8;
                header.DisplayIndex = column.DisplayIndex;
                headers.Add(header);
            }
            return headers.OrderBy(x => x.DisplayIndex).ToArray();
        }

    }
}
