using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Linq; using System.Text; using System.Windows.Forms; using ComponentFactory.Krypton.Toolkit; using System.Reflection; namespace NXWMS.Client.FrmCustom { /// /// DataGridView列操作控件 /// [ToolboxBitmap(typeof(System.Windows.Forms.Panel))] public partial class ColumnControl : UserControl { /// /// 字段值 /// [Description("字段操作对象")] public class ControlFieldValue { public string Code { get; set; } public string Name { get; set; } } [Description("被绑定的数据视图")] public DataGridView ToDataGridView { get; set; } [Description("数据视图中指定操作的列")] public DataGridViewColumn ItemColumn { get; set; } [Description("当前操作单元格矩形长宽坐标")] public Rectangle CellRectangle { get; set; } [Description("系统屏幕矩形长宽坐标")] public Rectangle ScreenRectangle { get; set; } [Description("选择按钮")] public KryptonButton ButtonSelect { get; set; } [Description("控件标题")] public string Title { get; set; } = ""; [Description("绑定控件对象")] public Control ItemControl { get; set; } [Description("是否允许输入(针对选择控件)")] public bool IsAllowInput { get; set; } = false; [Description("绑定控件对象类型")] public ControlType ItemControlType { get; set; } [Description("绑定控件对象数据")] public DataTable ItemControlData { get; set; } [Description("数据表格中查询显示列名称")] public Dictionary ItemColumnDic { get; set; } [Description("数据表格对应筛选字段")] public List ConditionColumnList { get; set; } [Description("弹窗数据视图条件")] public string ConditionColumnCode { get; set; } [Description("显示数据视图字段")] public string ShowColumns { get; set; } [Description("选择返回的字典编码")] public string ResultColumn { get; set; } [Description("设定弹出框位置(针对数据对象)")] public LocationType SetLocationType { get; set; } [Description("输入控件小数点长度(只针对浮点控件)")] public int InputDecimalLength { get; set; } = 0; [Description("输入控件最大值限制(只针对浮点控件)")] public int InputDecimalMax { get; set; } = 999999; [Description("输入控件最小值限制(只针对浮点控件)")] public int InputDecimalMin { get; set; } = 0; [Description("弹窗对象")] public Form ShowForm { get; set; } [Description("弹窗对象相对于屏幕显示的比例")] public double ShowFormProportion { get; set; } = 0.5; [Description("绑定控件对象类型")] public enum ControlType { ComboBox, Text, NumericUpDown, CheckBox, DataTime, Source, } public enum LocationType { Cell, ScreenCenter, } public enum OperationDataType { Selectd, Input, Other } /// /// 条件字段模型 /// public class ConditionColumnMode { public string Name { get; set; } public string Describe { get; set; } } /// /// 是否新增了选择列 /// private bool IsAddCheck { get; set; } /// /// 选择行索引列表 /// [Description("选择行索引列表")] public List CheckRowIndexList; [Description("最终操作是否未拖动")] public bool IsNoScroll = false; [Description("当前正在操作的单元格")] public DataGridViewCell CurrentDataGridViewCell; /// /// 数据视图控件模型 /// public class ControlDataViewModel { /// /// 数据控件名称 /// public string Name { get; set; } = Guid.NewGuid().ToString(); /// /// 数据控件描述 /// public string Describe { get; set; } /// /// 数据控件绑定对象 /// public DataGridView DataGridView { get; set; } /// /// 数据控件绑定对象中的列 /// public DataGridViewColumn DataGridViewColumn { get; set; } /// /// 数据控件绑定类型 /// public ControlType ControlType { get; set; } = ControlType.Text; /// /// 数据控件数据 /// public DataTable ControlData { get; set; } /// /// 数据视图筛选条件 /// public List ConditionColumnList { get; set; } /// /// 选择字段单元格显示 /// public string CellColumn { get; set; } /// /// 显示列 /// public Dictionary ItemColumnDic { get; set; } /// /// 结果字段 /// public string ResultColumn { get; set; } } /// /// 控件数据事件 /// /// 操作列 /// 对应列数据 /// 该控件操作数据类型 /// public delegate string ControlGetValueHandler(DataGridViewCell dataGridCell, object inData, OperationDataType operationDataType); public event ControlGetValueHandler ControlGetValueEvent; /// /// 按钮选择事件 /// /// 选择列 /// 选择行 /// 结果列名 /// public delegate string ButtonSelectHandler(DataGridViewColumn selectColumn, DataGridViewRow selectRow, string resultColumnName); public event ButtonSelectHandler ButtonSelectEvent; /// /// 当有选择列时,单独选择事件 /// /// 选择列 /// 选择行 /// 结果列名 /// public delegate string ControlCheckHandler(DataGridViewColumn selectColumn, DataGridViewRow selectRow, string resultColumnName); public event ControlCheckHandler ControlCheckEvent; /// /// 当有选择列时,去除选择事件 /// /// 选择列 /// 选择行 /// 结果列名 /// public delegate string ControlNoCheckHandler(DataGridViewColumn selectColumn, DataGridViewRow selectRow, string resultColumnName); public event ControlNoCheckHandler ControlNoCheckEvent; public event EventHandler ButtonExitEvent; public ColumnControl() { InitializeComponent(); Visible = false; LostFocus += new EventHandler(ColumnControl_LostFocus); this.Text = Title; } /// /// 组装 /// /// 控件数据模型 public void Build(ControlDataViewModel controlDataViewModel) { ConditionColumnList = controlDataViewModel.ConditionColumnList; //条件列表 ConditionColumnCode = controlDataViewModel.CellColumn; //单元格显示 ResultColumn = controlDataViewModel.ResultColumn; ItemControlData = controlDataViewModel.ControlData; ItemControlType = controlDataViewModel.ControlType; ToDataGridView = controlDataViewModel.DataGridView; ItemColumn = controlDataViewModel.DataGridViewColumn; ItemColumnDic = controlDataViewModel.ItemColumnDic; Build(); } /// /// 组装 /// private void Build() { ToDataGridView.CurrentCellChanged += new EventHandler(this.ToDataGridView_CurrentCellChanged); ToDataGridView.Scroll += new ScrollEventHandler(this.ToDataGridView_Scroll); ToDataGridView.ColumnWidthChanged += new DataGridViewColumnEventHandler(this.ToDataGridView_ColumnWidthChanged); ToDataGridView.CurrentCellDirtyStateChanged += new System.EventHandler(this.TodataGridView_CurrentCellDirtyStateChanged); ToDataGridView.SizeChanged += new System.EventHandler(this.ToDataGridView_SizeChanged); switch (ItemControlType) { case ControlType.CheckBox: ItemControl = new KryptonCheckBox(); ItemControl.KeyDown += new KeyEventHandler(ItemControl_KeyDown); ItemControl.Visible = false; break; case ControlType.ComboBox: ItemControl = new KryptonComboBox(); ItemControl.KeyDown += new KeyEventHandler(ItemControl_KeyDown); ItemControl.Visible = false; var fieldList = new List(); foreach (DataRow item in ItemControlData.Rows) { fieldList.Add(new ControlFieldValue { Code = item[ResultColumn].ToString(), Name = item[ConditionColumnCode].ToString() }); } (ItemControl as KryptonComboBox).AutoCompleteCustomSource.AddRange(fieldList.Select(s => s.Name).ToArray()); (ItemControl as KryptonComboBox).AutoCompleteSource = AutoCompleteSource.ListItems; (ItemControl as KryptonComboBox).AutoCompleteMode = AutoCompleteMode.SuggestAppend; (ItemControl as KryptonComboBox).DataSource = fieldList; (ItemControl as KryptonComboBox).DisplayMember = "Name"; (ItemControl as KryptonComboBox).ValueMember = "Code"; (ItemControl as KryptonComboBox).SelectedIndex = -1; if (!IsAllowInput) (ItemControl as KryptonComboBox).DropDownStyle = ComboBoxStyle.DropDownList; else (ItemControl as KryptonComboBox).DropDownStyle = ComboBoxStyle.DropDown; break; case ControlType.DataTime: ItemControl = new KryptonDateTimePicker(); ItemControl.KeyDown += new KeyEventHandler(ItemControl_KeyDown); ItemControl.Visible = false; break; case ControlType.NumericUpDown: ItemControl = new KryptonNumericUpDown(); ItemControl.KeyDown += new KeyEventHandler(ItemControl_KeyDown); ItemControl.Visible = false; (ItemControl as KryptonNumericUpDown).DecimalPlaces = InputDecimalLength; break; case ControlType.Text: ItemControl = new KryptonTextBox(); ItemControl.KeyDown += new KeyEventHandler(ItemControl_KeyDown); ItemControl.Visible = false; break; case ControlType.Source: ItemControl = this; ButtonSelect = new KryptonButton(); ButtonSelect.Visible = false; SetPanelCondition(ConditionColumnList); ButtonSelect.Click += new EventHandler(ShowPanelSelect_Click); ToDataGridView.Controls.Add(ButtonSelect); break; } ToDataGridView.Controls.Add(ItemControl); ToDataGridView.Controls.SetChildIndex(ItemControl, 99999); } private void ItemControl_KeyDown(object sender, KeyEventArgs e) { if (e.KeyValue == 13) { ItemControl_LostFocus(null, null); } } private void SetPanelCondition(List conditionColumnList) { //建立条件框 if (conditionColumnList.Any()) { tableLayoutPanelCondtion.Visible = true; for (int i = 0; i < conditionColumnList.Count; i++) { var lbCol = tableLayoutPanelCondtion.Controls.Find("lbCondition" + (i + 1).ToString(), true)[0]; if (lbCol != null) { var col = lbCol as KryptonLabel; col.Text = conditionColumnList[i].Describe; col.Visible = true; } var txtCol = tableLayoutPanelCondtion.Controls.Find("txtCondition" + (i + 1).ToString(), true)[0]; if (txtCol != null) { var col = txtCol as KryptonTextBox; col.Tag = conditionColumnList[i].Name; txtCol.TextChanged += new EventHandler(Condition_TextChanged); col.Visible = true; } } } } private void ToDataGridView_SizeChanged(object sender, EventArgs e) { ToDataGridView_CurrentCellChanged(null, null); } private void ToDataGridView_Scroll(object sender, ScrollEventArgs e) { if (ItemControlType == ControlType.Source) { Visible = false; ButtonSelect.Visible = false; } else { ItemControl.Visible = false; } ToDataGridView.ClearSelection(); IsNoScroll = true; } private void ToDataGridView_CellClick(object sender, DataGridViewCellEventArgs e) { if (IsNoScroll) { ToDataGridView_CurrentCellChanged(null, null); } } public void ToDataGridView_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e) { if (ItemControlType == ControlType.Source) { ToDataGridView_CurrentCellChanged(null, null); } } private void ToDataGridView_CurrentCellChanged(object sender, EventArgs e) { CurrentDataGridViewCell = ToDataGridView.CurrentCell; if (CurrentDataGridViewCell == null) return; var value = string.Empty; if (CurrentDataGridViewCell.Value == null) value = ""; else value = CurrentDataGridViewCell.Value.ToString(); if (CurrentDataGridViewCell != null && CurrentDataGridViewCell.RowIndex < ToDataGridView.Rows.Count && CurrentDataGridViewCell.OwningColumn.Name == ItemColumn.Name) { IsNoScroll = false; CellRectangle = ToDataGridView.GetCellDisplayRectangle(CurrentDataGridViewCell.ColumnIndex, CurrentDataGridViewCell.RowIndex, true); switch (ItemControlType) { case ControlType.CheckBox: ItemControl.Visible = true; (ItemControl as KryptonCheckBox).Text = ItemColumn.HeaderText; (ItemControl as KryptonCheckBox).Checked = Convert.ToBoolean(string.IsNullOrWhiteSpace(value) ? "FALSE" : value); break; case ControlType.ComboBox: (ItemControl as KryptonComboBox).Text = value; (ItemControl as KryptonComboBox).Focus(); break; case ControlType.DataTime: ItemControl.Visible = true; if (string.IsNullOrWhiteSpace(value)) { (ItemControl as KryptonDateTimePicker).Checked = false; } else { (ItemControl as KryptonDateTimePicker).Checked = true; (ItemControl as KryptonDateTimePicker).Value = DateTime.Parse(value); } (ItemControl as KryptonDateTimePicker).Focus(); break; case ControlType.NumericUpDown: ItemControl.Visible = true; if (string.IsNullOrWhiteSpace(value)) { (ItemControl as KryptonNumericUpDown).Value = 0; } else { (ItemControl as KryptonNumericUpDown).Value = Convert.ToDecimal(value); } (ItemControl as KryptonNumericUpDown).Maximum = InputDecimalMax; (ItemControl as KryptonNumericUpDown).Minimum = InputDecimalMin; (ItemControl as KryptonNumericUpDown).Focus(); break; case ControlType.Text: ItemControl.Visible = true; (ItemControl as KryptonTextBox).Text = Convert.ToString(value); (ItemControl as KryptonTextBox).Focus(); break; case ControlType.Source: ButtonSelect.Top = CellRectangle.Top; ButtonSelect.StateCommon.Content.ShortText.Font = new Font("宋体", 7.5f); ButtonSelect.Text = ".."; ButtonSelect.Left = CellRectangle.Left + CellRectangle.Size.Width - 30; ButtonSelect.Size = new Size(30, CellRectangle.Size.Height); ButtonSelect.Visible = true; return; } ItemControl.Size = CellRectangle.Size; ItemControl.Top = CellRectangle.Top; ItemControl.Left = CellRectangle.Left; ItemControl.Visible = true; ItemControl.LostFocus += new EventHandler(ItemControl_LostFocus); ItemControl.GotFocus += new EventHandler(ItemControl_GostFocus); } else { if (ButtonSelect != null) { ButtonSelect.Visible = false; } ItemControl.Visible = false; } } public void AddMultipleCheck(int index) { if (ItemControlType == ControlType.Source) { IsAddCheck = true; ItemControlData.Columns.Add("#SELECTED", typeof(bool)); } } private void TodataGridView_CurrentCellDirtyStateChanged(object sender, EventArgs e) { CurrentDataGridViewCell.Value = ""; } private void dataGridViewSelect_CellClick(object sender, DataGridViewCellEventArgs e) { if (e.RowIndex >= 0 && e.ColumnIndex == 0) { if (this.dataGridViewSelect.Rows[e.RowIndex].Cells[e.ColumnIndex].Value == null) { if (!CheckRowIndexList.Where(s => s == e.RowIndex).Any()) { CheckRowIndexList.Add(e.RowIndex); } ControlCheckEvent?.Invoke(ItemColumn, dataGridViewSelect.SelectedRows[0], ResultColumn); this.dataGridViewSelect.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = 1; } else if (dataGridViewSelect.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString() == "1") { if (CheckRowIndexList.Where(s => s == e.RowIndex).Any()) { CheckRowIndexList.Remove(e.RowIndex); } ControlNoCheckEvent?.Invoke(ItemColumn, dataGridViewSelect.SelectedRows[0], ResultColumn); this.dataGridViewSelect.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = 0; } else { if (!CheckRowIndexList.Where(s => s == e.RowIndex).Any()) { CheckRowIndexList.Add(e.RowIndex); } ControlCheckEvent?.Invoke(ItemColumn, dataGridViewSelect.SelectedRows[0], ResultColumn); this.dataGridViewSelect.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = 1; } } } private void ShowPanelSelect_Click(object sender, EventArgs e) { if (dataGridViewSelect.Columns.Count == 0) { dataGridViewSelect.DataSource = ItemControlData; if (ConditionColumnList.Any()) { foreach (DataGridViewColumn item in dataGridViewSelect.Columns) { item.Visible = false; } foreach (var item in ConditionColumnList) { if (dataGridViewSelect.Columns.Contains(item.Name)) { dataGridViewSelect.Columns[item.Name].Visible = true; dataGridViewSelect.Columns[item.Name].HeaderText = item.Describe; dataGridViewSelect.Columns[item.Name].ReadOnly = true; } } } if (IsAddCheck) { dataGridViewSelect.CellClick += new DataGridViewCellEventHandler(dataGridViewSelect_CellClick); dataGridViewSelect.Columns["#SELECTED"].DisplayIndex = 0; dataGridViewSelect.Columns["#SELECTED"].Visible = true; dataGridViewSelect.Columns["#SELECTED"].ReadOnly = false; dataGridViewSelect.Columns["#SELECTED"].HeaderText = "选择"; dataGridViewSelect.Columns["#SELECTED"].Resizable = DataGridViewTriState.False; dataGridViewSelect.Columns["#SELECTED"].Frozen = false; //dataGridViewSelect.Columns["#SELECTED"].Width = 20; dataGridViewSelect.Columns["#SELECTED"].ReadOnly = false; dataGridViewSelect.Columns["#SELECTED"].DefaultCellStyle.ForeColor = Color.Red; } else { ToDataGridView.CellDoubleClick += new DataGridViewCellEventHandler(this.dataGridViewSelect_CellDoubleClick); } } var cellHeight = ToDataGridView.GetCellDisplayRectangle(ToDataGridView.CurrentCell.ColumnIndex, ToDataGridView.CurrentCell.RowIndex, true).Height; this.Size = new Size(497, 337); switch (SetLocationType) { case LocationType.ScreenCenter: ScreenRectangle = Screen.GetWorkingArea(this); this.Location = new Point((ScreenRectangle.Width - Width) / 2, (ScreenRectangle.Height - Height) / 2); break; default: ItemControl.Top = CellRectangle.Top + cellHeight; ItemControl.Left = CellRectangle.Left; break; } if (SetLocationType == LocationType.Cell) { ToDataGridView.Controls.Add(ButtonSelect); this.Visible = true; } else { this.Visible = true; AddFormShow(); ShowForm.ShowDialog(); } } private void AddFormShow() { this.Visible = true; this.Dock = DockStyle.Fill; var newUserControl = this; newUserControl.Dock = DockStyle.Fill; ShowForm = new Form(); ShowForm.Name = "ShowDiagion"; ShowForm.StartPosition = FormStartPosition.CenterScreen; ShowForm.MaximizeBox = true; ShowForm.MinimizeBox = false; ShowForm.Location = newUserControl.Location; ShowForm.Size = new Size { Height = Convert.ToInt32(ScreenRectangle.Height * ShowFormProportion), Width = Convert.ToInt32(ScreenRectangle.Width * ShowFormProportion), }; ShowForm.Text = newUserControl.Title; ShowForm.Controls.Add(newUserControl); } private void ItemControl_LostFocus(object sender, EventArgs e) { OperationDataType operationTemp; object value = null; switch (ItemControlType) { case ControlType.CheckBox: CurrentDataGridViewCell.Style.ForeColor = Color.Red; CurrentDataGridViewCell.Value = (ItemControl as KryptonCheckBox).Checked; ControlGetValueEvent?.Invoke(CurrentDataGridViewCell, (ItemControl as KryptonCheckBox).Checked, OperationDataType.Selectd); break; case ControlType.ComboBox: CurrentDataGridViewCell.Style.ForeColor = Color.Red; if ((ItemControl as KryptonComboBox).SelectedValue == null) { value = (ItemControl as KryptonComboBox).Text; operationTemp = OperationDataType.Input; } else { value = (ItemControl as KryptonComboBox).SelectedValue.ToString(); operationTemp = OperationDataType.Selectd; } CurrentDataGridViewCell.Value = (ItemControl as KryptonComboBox).Text; CurrentDataGridViewCell.Tag = value; ControlGetValueEvent?.Invoke(CurrentDataGridViewCell, value, operationTemp); break; case ControlType.DataTime: CurrentDataGridViewCell.Style.ForeColor = Color.Red; if ((ItemControl as KryptonDateTimePicker).Checked) { value = (ItemControl as KryptonDateTimePicker).Value; CurrentDataGridViewCell.Value = value; } operationTemp = OperationDataType.Input; ControlGetValueEvent?.Invoke(CurrentDataGridViewCell, value, OperationDataType.Input); break; case ControlType.NumericUpDown: CurrentDataGridViewCell.Style.ForeColor = Color.Red; CurrentDataGridViewCell.Value = (ItemControl as KryptonNumericUpDown).Value; ControlGetValueEvent?.Invoke(CurrentDataGridViewCell, (ItemControl as KryptonNumericUpDown).Value, OperationDataType.Input); break; case ControlType.Text: CurrentDataGridViewCell.Style.ForeColor = Color.Red; CurrentDataGridViewCell.Value = (ItemControl as KryptonTextBox).Text; ControlGetValueEvent?.Invoke(CurrentDataGridViewCell, (ItemControl as KryptonTextBox).Text, OperationDataType.Input); break; case ControlType.Source: kryptonButtonSelect_Click(null, null); break; } } private void ItemControl_GostFocus(object sender, EventArgs e) { } private void ColumnControl_LostFocus(object sender, EventArgs e) { if (this.Visible) { this.Visible = false; ItemControl_LostFocus(null, null); } } private void kryptonButtonSelect_Click(object sender, EventArgs e) { if (dataGridViewSelect.SelectedRows.Count == 0) { return; } var selectIndex = dataGridViewSelect.SelectedRows[0].Index; if (selectIndex >= 0) { CurrentDataGridViewCell.Value = ItemControlData.Rows[selectIndex][ResultColumn]; CurrentDataGridViewCell.Tag = string.IsNullOrWhiteSpace(ConditionColumnCode) ? ItemControlData.Rows[selectIndex][ConditionColumnList.FirstOrDefault().Name] : ItemControlData.Rows[selectIndex][ResultColumn]; ButtonSelect.Visible = false; ButtonSelectEvent?.Invoke(ItemColumn, dataGridViewSelect.SelectedRows[0], ResultColumn); ShowForm.Hide(); } else { KryptonMessageBox.Show($"请选择!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information); } } private void kryptonButtonExit_Click(object sender, EventArgs e) { if (ItemControlType == ControlType.Source) { this.Visible = false; ButtonSelect.Visible = false; ShowForm.Close(); } else { ItemControl.Visible = false; } ButtonExitEvent?.Invoke(sender, e); } private void dataGridViewSelect_CellDoubleClick(object sender, DataGridViewCellEventArgs e) { if (ShowForm.Visible) { kryptonButtonSelect_Click(null, null); } } private void ColumnControl_Resize(object sender, EventArgs e) { } private void Condition_TextChanged(object sender, EventArgs e) { var txtCol = sender as KryptonTextBox; var likeSql = $"`{txtCol.Tag}` like '%{txtCol.Text}%'"; DataRow[] dataRows = ItemControlData.Select(likeSql); if (dataRows == null || !dataRows.Any()) { var dataTemp = ItemControlData.Copy(); dataTemp.Rows.Clear(); dataGridViewSelect.DataSource = dataTemp; } else { var result = dataRows.CopyToDataTable(); dataGridViewSelect.DataSource = result; } } } }