/******************************************************************************* * Copyright(c) 2014 DongkeSoft All rights reserved. / Confidential * 类的信息: * 1.程序名称:C_TXT_DropDownList.cs * 2.功能描述:扩展的控件 * 编辑履历: * 作者 日期 版本 修改内容 * 陈晓野 2014/09/29 1.00 新建 *******************************************************************************/ using Dongke.IBOSS.PRD.Basics.Library; using System; using System.ComponentModel; using System.Data; using System.Drawing; using System.Windows.Forms; namespace Dongke.IBOSS.PRD.Basics.BaseControls { public partial class C_TXT_DropDownList : DKTextBoxBase { #region 成员变量 public ListBox _lstShowChoice = null; // 弹出的选择下拉选项 private Color _lstForeColor = Color.Gray; // 弹出的选择下拉选项前景色 private Color _lstBackColor = Color.Snow; // 弹出的选择下拉选项背景色 private DataTable _dataSource; // 本控件的数据源 private string _displayMember; // 控件下拉选择项显示的属性 private string _valueMember; // 控件下拉选择项实际值的属性 private bool _allowSpace = true; // 是否允许输入空格 private bool _dropDownOnly = true; // 只能从下拉选项中选择值 public int _originalLocation = 0; // 光标原来的位置 public string _originalText = ""; // 文本框原来的文本值 public bool _isKeyDown = false; // 是否按下了键盘 private object _selectedValue = ""; // 下拉选择选中的值 private object _selectedItem = ""; private bool _IsOnlyShowValid = true; // 是否只显示有效数据 private bool _isSetPosition = true; #endregion public C_TXT_DropDownList() { InitializeComponent(); IsSetPosition = false; this.Leave += new EventHandler(dkDropDownList_Leave); this.KeyDown += new KeyEventHandler(dkDropDownList_KeyDown); this.KeyUp += new KeyEventHandler(dkDropDownList_KeyUp); this.DoubleClick += new EventHandler(dkDropDownList_DoubleClick); } public C_TXT_DropDownList(IContainer container) { container.Add(this); InitializeComponent(); this.Leave += new EventHandler(dkDropDownList_Leave); this.KeyDown += new KeyEventHandler(dkDropDownList_KeyDown); this.KeyUp += new KeyEventHandler(dkDropDownList_KeyUp); this.DoubleClick += new EventHandler(dkDropDownList_DoubleClick); } #region 公开属性 /// /// 设定或者取得本控件的数据源 /// [Description("设定或者取得本控件的数据源")] public DataTable DataSource { get { return _dataSource; } set { _dataSource = (DataTable)SetFilter(value); ListBox lstBox = this.lstPrompt; if (lstBox != null) { SetParentBySummary(); lstBox.DataSource = _dataSource; lstBox.DisplayMember = _displayMember; lstBox.ValueMember = _valueMember; } } } /// /// 设定或者获取控件是否可以输入空格 /// [Description("设定或者获取控件是否可以输入空格")] [DefaultValue(true)] public bool AllowSpace { get { return _allowSpace; } set { _allowSpace = value; } } /// /// 设定或者获取控件是否只能从下拉选项中选择值 /// [Description("设定或者获取控件是否只能从下拉选项中选择值")] [DefaultValue(true)] public bool DropDownOnly { get { return _dropDownOnly; } set { _dropDownOnly = value; } } /// /// 指示要为下拉选择项显示的属性 /// [Description("指示要为下拉选择项显示的属性")] public string DisplayMember { get { return _displayMember; } set { _displayMember = value; } } /// /// 指示要为下拉选择项实际值的属性 /// [Description("指示要为下拉选择项实际值的属性")] public string ValueMember { get { return _valueMember; } set { _valueMember = value; } } /// /// 控件的值 /// [Description("取得和设定与控件关联的值,即valueMember对应的值")] public object SelectedValue { get { return _selectedValue; } set { _selectedValue = value; if (string.IsNullOrEmpty(value + "")) { this.Text = string.Empty; } if (_selectedValue != null && _selectedValue.ToString() != "" && this.DataSource != null) { DataTable tempTable = this.DataSource.Copy(); DataRow[] dataRows = tempTable.Select(ValueMember.ToUpper() + " = '" + this._selectedValue + "'"); if (dataRows.Length == 1) { this.Text = dataRows[0][DisplayMember] as string; } } } } /// /// 重新设置位置 /// [DefaultValue(true)] public bool IsSetPosition { set { _isSetPosition = value; } get { return _isSetPosition; } } /// /// 是否只显示有效数据 /// [Description("设置控件是否只显示有效数据。")] [DefaultValue(true)] public bool IsOnlyShowValid { get { return _IsOnlyShowValid; } set { _IsOnlyShowValid = value; } } public ListBox lstPrompt { get { //如果没有列表用于显示提示的列表框,则创建一个 if ((_lstShowChoice == null) && this.Parent != null) { _lstShowChoice = new ListBox(); _lstShowChoice.Visible = false;//false _lstShowChoice.Left = this.Left; _lstShowChoice.Top = this.Bottom; _lstShowChoice.Width = this.Width; _lstShowChoice.TabStop = false; _lstShowChoice.Sorted = true; _lstShowChoice.ForeColor = this._lstForeColor; // 前景色 _lstShowChoice.BackColor = this._lstBackColor; // 背景色 _lstShowChoice.BorderStyle = BorderStyle.FixedSingle; IsSetPosition = false; //如果提示框过低,则显示到上面 if (_lstShowChoice.Bottom > this.Parent.Height) { _lstShowChoice.Top = this.Top - _lstShowChoice.Height + 8; } if (!IsSetPosition) { this.Parent.Controls.Add(_lstShowChoice); this.Parent.ResumeLayout(false); //this.Controls.Add(_lstShowChoice); //this.ResumeLayout(false); } // 注册鼠标移动、点击事件 _lstShowChoice.MouseUp += new MouseEventHandler(lstBox_MouseUp); _lstShowChoice.MouseMove += new MouseEventHandler(lstBox_MouseMove); //this.Parent.Controls.Add(_lstShowChoice); //this.Parent.ResumeLayout(false); _lstShowChoice.BringToFront(); } return _lstShowChoice; } } //void _lstShowChoice_DrawItem(object sender, DrawItemEventArgs e) //{ // _lstShowChoice.DrawMode = DrawMode.OwnerDrawFixed; // e.DrawBackground(); // Brush myBrush = Brushes.Black; // FontFamily fontFamily = new FontFamily("宋体"); // System.Drawing.Font myFont = new Font(fontFamily,10); // if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) // { // //e.Graphics.FillRectangle(Brushes.Blue, e.Bounds); // if (e.Index > -1) // { // e.Graphics.DrawString(_lstShowChoice.Items[e.Index].ToString(), myFont, Brushes.White, e.Bounds, StringFormat.GenericDefault); // } // } // else // { // //e.Graphics.FillRectangle(Brushes.White, e.Bounds); // if (e.Index > -1) // { // e.Graphics.DrawString(_lstShowChoice.Items[e.Index].ToString(), myFont, myBrush, e.Bounds, StringFormat.GenericDefault); // } // } // e.DrawFocusRectangle(); //} /// /// 弹出的选择下拉选项前景色 /// [Description("取得和设定弹出的选择下拉选项前景色")] public Color PromptForeColor { get { return _lstForeColor; } set { _lstForeColor = value; ListBox lstBox = this.lstPrompt; SetParentBySummary(); if (lstBox != null) { lstBox.ForeColor = _lstForeColor; } } } /// /// 弹出的选择下拉选项背景色 /// [Description("取得和设定弹出的选择下拉选项背景色")] public Color PromptBackColor { get { return _lstBackColor; } set { _lstBackColor = value; ListBox lstBox = this.lstPrompt; if (lstBox != null) { SetParentBySummary(); lstBox.BackColor = _lstBackColor; } } } #endregion #region 私有方法或者函数 /// /// 鼠标点击下拉选择项时,选中处理 /// /// /// private void lstBox_MouseUp(object sender, MouseEventArgs e) { if (_selectedItem != null) { DataRowView dataRowView = _selectedItem as DataRowView; if (dataRowView != null) { this.Text = dataRowView[_displayMember].ToString(); this._selectedValue = dataRowView[_valueMember].ToString(); } this.SelectionStart = this.Text.Length; //选择后文本框失去了焦点,这里移回来 this.Focus(); } } /// /// 鼠标经过下拉选择项时,选中处理 /// /// /// private void lstBox_MouseMove(object sender, MouseEventArgs e) { ListBox lstBox = (ListBox)sender; Point point = new Point(e.X, e.Y); int n = lstBox.IndexFromPoint(point); if (n >= 0) { lstBox.SelectedIndex = n; _selectedItem = lstBox.SelectedItem; } } /// /// 在本控件中按下了键盘的任何键 /// /// /// private void dkDropDownList_KeyDown(object sender, KeyEventArgs e) { //_lstShowChoice.Visible = true; if (_lstShowChoice != null) { _lstShowChoice.Visible = true; } _originalLocation = this.SelectionStart; _isKeyDown = true; _originalText = this.Text; } /// /// 在本控件中按下了键盘的任何键,进行匹配处理 /// /// /// private void dkDropDownList_KeyUp(object sender, KeyEventArgs e) { if (!_isKeyDown) { return; } // 将按下键标识置回原始状态 _isKeyDown = false; ListBox lstBox = this.lstPrompt; //SetParentBySummary(); switch (e.KeyCode) { // 通过上下箭头在待选框中移动 case Keys.Up: case Keys.Down: if ((lstBox != null) && !this.Multiline) // 多行文本通过上下箭头在两行之间移动 { if ((e.KeyCode == Keys.Up) && (lstBox.SelectedIndex > -1)) // ↑ { lstBox.SelectedIndex--; } else if ((e.KeyCode == Keys.Down) && (lstBox.SelectedIndex < lstBox.Items.Count - 1)) //↑ { lstBox.SelectedIndex++; } //上下箭头不能移动当前光标,因此,还原原来位置 this.SelectionStart = _originalLocation; //显示提示框 if (!lstBox.Visible) { if (lstBox.Width != this.Width) { lstBox.Width = this.Width; } lstBox.Visible = true; } } break; case Keys.Escape: // ESC隐藏提示 this.Text = string.Empty; this._selectedValue = string.Empty; if ((lstBox != null) && lstBox.Visible) { lstBox.Hide(); } break; case Keys.Return: // 回车选择一个或跳到下一控件 if ((lstBox == null) || this.Multiline) { break; } // 没有显示提示框时,移动到下一控件 if (!lstBox.Visible) { SendKeys.Send("{TAB}"); } else // 有提示,关闭提示 { if (lstBox.SelectedIndex > -1) // 有选择,使用当前选择的内容 { DataRowView dataRowView = lstBox.SelectedItem as DataRowView; if (dataRowView != null) { this.Text = dataRowView[_displayMember].ToString(); this._selectedValue = dataRowView[_valueMember].ToString(); } } this.SelectionStart = this.Text.Length; this.SelectAll(); lstBox.Hide(); } break; // 按delete键清空 case Keys.Delete: this.Text = string.Empty; this._selectedValue = string.Empty; if ((lstBox != null) && lstBox.Visible) { lstBox.Hide(); } break; default: // 判断文本是否改变 string textString = this.Text; // 不允许产生空格,去掉文本中的空格 if (!this.AllowSpace) { textString = this.Text.Replace(" ", ""); } int nStart = this.SelectionStart; if (textString != _originalText) // 文本有改变 { // 设置当前文本和键盘光标位置 this.Text = textString; if (nStart > this.Text.Length) { nStart = this.Text.Length; } this.SelectionStart = nStart; //修改可供选择的内容,并显示供选择的列表框 if (lstBox != null) { FillPrompt(textString); if (!lstBox.Visible) { if (lstBox.Width != this.Width) { lstBox.Width = this.Width; } lstBox.Visible = true; } } } break; } } /// /// 为下拉选择赋值 /// /// 匹配内容 private void FillPrompt(string searchText) { //return; ListBox lstBox = this.lstPrompt; if (lstBox != null && _dataSource != null) { SetParentBySummary(); //BY 赵含 编号:C帐套补充一览105、106 // string filter = DisplayMember + " LIKE '%" + Utility.SelectFilterLike(searchText) + "%'"; //string filter = Utility.SelectFilterLike(searchText); string filter = DisplayMember + " LIKE '%" + (Utility.SelectFilterLike(this.Text)).Replace(@"*", @"[*]") + "%'"; // string filter = DisplayMember + " LIKE '%" + searchText + "%'"; _dataSource.DefaultView.RowFilter = filter; DataTable returnTable = _dataSource.DefaultView.ToTable(); lstBox.DataSource = returnTable; lstBox.Refresh(); _selectedItem = lstBox.SelectedItem; } } /// /// 下拉选择项失去焦点处理 /// /// /// private void dkDropDownList_Leave(object sender, EventArgs e) { //return; ListBox lstBox = this.lstPrompt; // 对于只选字段,必须输入同待选相匹配的值 if (this.DropDownOnly && _dataSource != null) { //BY 赵含 编号:C帐套补充一览105、106 //string filter = DisplayMember + " LIKE '%" + Utility.SelectFilterLike(this.Text) + "%'"; string filter = DisplayMember + " LIKE '%" + (Utility.SelectFilterLike(this.Text)).Replace(@"*", @"[*]") + "%'"; _dataSource.DefaultView.RowFilter = filter; DataTable returnTable = _dataSource.DefaultView.ToTable(); if (returnTable.Rows.Count > 0) { DataRowView dataRowView = _selectedItem as DataRowView; if (lstBox != null && lstBox.Visible) { if (dataRowView != null) { this.Text = dataRowView[DisplayMember] + ""; this._selectedValue = dataRowView[ValueMember] + ""; } else { this.Text = returnTable.Rows[0][DisplayMember] + ""; this._selectedValue = returnTable.Rows[0][ValueMember]; } } else { //this.Text = ""; //this._selectedValue = null; } } else { this.Text = ""; this._selectedValue = null; } } // 失去焦点后,必须隐藏提示 lstBox = this.lstPrompt; if (lstBox != null) { lstBox.Visible = false; } } /// /// 本控件双击事件 /// /// /// private void dkDropDownList_DoubleClick(object sender, EventArgs e) { if (this.ReadOnly || !this.Enabled) { return; } ListBox lstBox = this.lstPrompt; FillPrompt(this.Text); if ((lstBox != null) && (!lstBox.Visible)) { SetParentBySummary(); if (lstBox.Width != this.Width) { lstBox.Width = this.Width; } lstBox.Visible = true; } } /// /// 过滤数据源 /// /// /// protected object SetFilter(object dataSource) { //string filter = "ValueFlag = 1"; if (dataSource is BindingSource) { BindingSource bSource = (BindingSource)dataSource; // 若设置了只显示有效数据 if (this._IsOnlyShowValid == true) { //bSource.Filter = filter; } dataSource = bSource; } else if (dataSource is DataTable) { DataTable dtbl = (DataTable)dataSource; // 若设置了只显示有效数据 if (this._IsOnlyShowValid == true) { //dtbl.DefaultView.RowFilter = filter; } dataSource = dtbl.DefaultView.ToTable(); } return dataSource; } /// /// 科目汇总时使用 /// private void SetParentBySummary() { // 周兴 2018-4-7 注释 //if (this.Parent != null && IsSetPosition) if (this.Parent != null) { _lstShowChoice.Left = this.Left + this.Parent.Left; _lstShowChoice.Top = this.Bottom + this.Parent.Top; Control control = this.Parent.Parent; if (control != null) { control.Controls.Add(_lstShowChoice); control.ResumeLayout(false); _lstShowChoice.BringToFront(); } } } #endregion } }