/******************************************************************************* * Copyright(c) 2014 DongkeSoft All rights reserved. / Confidential * 类的信息: * 1.程序名称:DKListBoxComboBox.cs * 2.功能描述:下拉列表控件:根据输入内容进行模糊查询 * 编辑履历: * 作者 日期 版本 修改内容 * 陈晓野 2014/09/04 1.00 新建 *******************************************************************************/ using System; using System.ComponentModel; using System.Data; using System.Drawing; using System.Windows.Forms; using Dongke.IBOSS.PRD.Basics.Library; namespace Dongke.IBOSS.PRD.Basics.BaseControls { /// /// 下拉列表控件:根据输入内容进行模糊查询 /// public partial class DKListBoxComboBox : PopupComboBox { #region 委托声明 #endregion #region 事件声明 #endregion #region 常量 #endregion #region 成员变量 ListControlContainer _containerControl = null; /// /// 多选控件 /// private C_ListBox _listBox; /// /// 只能从下拉选项中选择值 /// private bool _dropDownOnly = true; /// /// 下拉列表显示中 /// private bool _isDropDownShowing = false; /// /// 下拉列表显示状态 /// private bool _isDropDownClose = true; /// /// Form事件设定 /// private bool _isSetting = false; #endregion #region 构造函数 /// /// 构造函数 /// public DKListBoxComboBox() : base() { InitializeComponent(); this._listBox = new C_ListBox(); this._containerControl = new ListControlContainer(); this._containerControl.Controls.Add(this._listBox); this._containerControl.Padding = new Padding(0, 0, 0, 12); this._listBox.Dock = DockStyle.Fill; this._listBox.IntegralHeight = false; this.DropDownControl = this._containerControl; this.dropDown.Resizable = true; this.dropDown.FocusOnOpen = false; this.dropDown.AutoClose = false; this.dropDown.Opening += this.dropDown_Opening; this.dropDown.Closed += this.dropDown_Closed; this._listBox.SelectedIndexChanged += this.ListBox_SelectedIndexChanged; this.Leave += this.DKListBoxComboBox_Leave; this.KeyDown += this.DKListBoxComboBox_KeyDown; this.TextChanged += this.DKListBoxComboBox_TextChanged; this.KeyUp += this.DKListBoxComboBox_KeyUp; this.LocationChanged += this.DKListBoxComboBox_LocationChanged; this.SizeChanged += this.DKListBoxComboBox_SizeChanged; //this.DropDown += DKListBoxComboBox_DropDown; //this.DropDownClosed += DKListBoxComboBox_DropDownClosed; } void ShowCbDropDown() { //this.OnDropDown(null); this.ShowDropDown(); } void HideCbDropDown() { //this.OnDropDownClosed(null); this.HideDropDown(); } //void DKListBoxComboBox_DropDownClosed(object sender, EventArgs e) //{ // try // { // this.HideDropDown(); // } // catch (Exception ex) // { // throw ex; // } //} //void DKListBoxComboBox_DropDown(object sender, EventArgs e) //{ // try // { // this.ShowDropDown(); // } // catch (Exception ex) // { // throw ex; // } //} #endregion #region 单例模式 #endregion #region 属性 /// /// 获取或设置控件的数据源 /// public new DataTable DataSource { get { return this._listBox.DataSource as DataTable; } set { this._listBox.DataSource = value; } } /// /// 获取或设置一个字符串,该字符串指定要显示其内容的列表框中所含对象的属性 /// public new string DisplayMember { get { return this._listBox.DisplayMember; } set { this._listBox.DisplayMember = value; } } /// /// 获取或设置一个字符串,该字符串指定要从中取值的数据源的属性 /// public new string ValueMember { get { return this._listBox.ValueMember; } set { this._listBox.ValueMember = value; } } /// /// 设定或者获取控件是否只能从下拉选项中选择值 /// [Description("设定或者获取控件是否只能从下拉选项中选择值")] [DefaultValue(true)] public bool DropDownOnly { get { return this._dropDownOnly; } set { this._dropDownOnly = value; } } /// /// Items /// [Browsable(true)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public new ListBox.ObjectCollection Items { get { return this._listBox.Items; } } /// /// 选项 /// [Browsable(true)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public C_ListBox ListBox { get { return this._listBox; } } public new object SelectedValue { get { return this._listBox.SelectedValue; } set { this.SetDataSource(null); if (value != null) { this._listBox.SelectedValue = value; } } } public new string Text { get { return base.Text; } set { base.Text = value; //this.SetDataSource(value); this.ListBox_SelectedIndexChanged(this, null); } } #endregion #region 事件处理 /// /// 下拉列表打开 /// /// /// private void dropDown_Opening(object sender, CancelEventArgs e) { //try //{ // this._listBox.SelectedIndexChanged -= this.ListBox_SelectedIndexChanged; // this._listBox.ClearSelected(); // this._listBox.SelectedIndexChanged += this.ListBox_SelectedIndexChanged; //} //catch (Exception ex) //{ // throw ex; //} } /// /// 下拉列表关闭 /// /// /// private void dropDown_Closed(object sender, ToolStripDropDownClosedEventArgs e) { } /// /// 文本框值改变 /// /// /// private void DKListBoxComboBox_TextChanged(object sender, EventArgs e) { try { this.SetDataSource(base.Text); } catch (Exception ex) { throw ex; } } /// /// /// /// /// private void DKListBoxComboBox_KeyUp(object sender, KeyEventArgs e) { try { int boxSelectedIndex = this.ListBox.SelectedIndex; int boxItemCount = this.ListBox.Items.Count; switch (e.KeyCode) { // 通过上下箭头在待选框中移动 case Keys.Up: if (boxItemCount > 0) { boxSelectedIndex--; if (boxSelectedIndex < -1) { boxSelectedIndex = boxItemCount - 1; } this._isDropDownClose = false; this._listBox.SelectedIndexChanged -= this.ListBox_SelectedIndexChanged; if (boxSelectedIndex == -1) { this.ListBox.ClearSelected(); } else { this.ListBox.SelectedIndex = boxSelectedIndex; } this._listBox.SelectedIndexChanged += this.ListBox_SelectedIndexChanged; this._isDropDownClose = true; } break; case Keys.Down: if (boxItemCount > 0) { boxSelectedIndex++; if (boxSelectedIndex >= boxItemCount) { boxSelectedIndex = -1; } this._isDropDownClose = false; this._listBox.SelectedIndexChanged -= this.ListBox_SelectedIndexChanged; if (boxSelectedIndex == -1) { this._listBox.ClearSelected(); this._listBox.SelectedItem = null; } else { this._listBox.SelectedIndex = boxSelectedIndex; } this._listBox.SelectedIndexChanged += this.ListBox_SelectedIndexChanged; this._isDropDownClose = true; } break; case Keys.Escape: // ESC隐藏提示 //this.ResetSelectedValue(); break; case Keys.Return: // 回车选择 在输入法中按回车也会响应这个事件 this.ResetSelectedValue(); break; default: break; } } catch (Exception ex) { throw ex; } } /// /// 输入文本框值 /// /// /// private void DKListBoxComboBox_KeyDown(object sender, KeyEventArgs e) { try { this.ShowCbDropDown(); } catch (Exception ex) { throw ex; } } /// /// Form大小改变 /// /// /// private void form_SizeChanged(object sender, EventArgs e) { try { this.HideCbDropDown(); Control control = sender as Control; if (control != null) { control.Refresh(); } } catch (Exception ex) { throw ex; } } /// /// Form位置改变 /// /// /// private void form_LocationChanged(object sender, EventArgs e) { try { this.HideCbDropDown(); } catch (Exception ex) { throw ex; } } /// /// Form失去焦点时 /// /// /// private void form_Deactivate(object sender, EventArgs e) { try { // listbox不能改变大小,不能移动滚动条 //this.HideCbDropDown(); } catch (Exception ex) { throw ex; } } /// /// Form激活 /// /// /// void form_Activated(object sender, EventArgs e) { try { this.HideCbDropDown(); } catch (Exception ex) { throw ex; } } /// /// 焦点离开 /// /// /// private void DKListBoxComboBox_Leave(object sender, EventArgs e) { try { this.ResetSelectedValue(); } catch (Exception ex) { throw ex; } } /// /// 选项改变 /// /// /// private void ListBox_SelectedIndexChanged(object sender, EventArgs e) { try { if (this._listBox.SelectedItem == null) { base.Text = string.Empty; } else { this.TextChanged -= this.DKListBoxComboBox_TextChanged; base.Text = this._listBox.GetItemText(this._listBox.SelectedItem); this.TextChanged += this.DKListBoxComboBox_TextChanged; } this.SelectionStart = base.Text.Length; this.HideDropDown(); } catch (Exception ex) { throw ex; } } /// /// 尺寸改变 /// /// /// private void DKListBoxComboBox_SizeChanged(object sender, EventArgs e) { try { this.HideCbDropDown(); } catch (Exception ex) { throw ex; } } /// /// 位置改变 /// /// /// private void DKListBoxComboBox_LocationChanged(object sender, EventArgs e) { try { this.HideCbDropDown(); } catch (Exception ex) { throw ex; } } #endregion #region 公有方法/函数 /// /// 显示下拉列表 /// public override void ShowDropDown() { if (this.Enabled && !this.dropDown.Visible) { if (!_isSetting) { _isSetting = true; Control control = this.Parent; while (control != null && !(control is Form)) { control = control.Parent; } Form form = control as Form; if (form != null) { form.LocationChanged += form_LocationChanged; form.SizeChanged += form_SizeChanged; form.Deactivate += form_Deactivate; form.Activated += form_Activated; } } //int itemCount = this.ListBox.Items.Count; //this._containerControl.Height = itemCount * 20; this._isDropDownShowing = true; base.ShowDropDown(); this._isDropDownShowing = false; int selectionStart = this.SelectionStart; int selectionLength = this.SelectionLength; this.Focus(); this.SelectionStart = selectionStart; this.SelectionLength = selectionLength; } } /// /// 关闭下拉列表 /// public override void HideDropDown() { if (this.dropDown.Visible && this._isDropDownClose) { base.HideDropDown(); this.dropDown.Close(); this.dropDown.Visible = false; } } #endregion #region 受保护方法/函数 /// /// 改变大小 /// /// protected override void OnResize(EventArgs e) { // When the ComboBox is resized, the width of the dropdown // is also resized to match the width of the ComboBox. I think it looks better. Size Size = new Size(Width, DropDownControl.Height); dropDown.Size = Size; base.OnResize(e); } #endregion #region 私有方法/函数 /// /// /// internal void ResetSelectedValue() { if (this._isDropDownShowing) { return; } this.HideCbDropDown(); if (this._listBox.SelectedItem != null) { base.Text = this._listBox.GetItemText(this._listBox.SelectedItem); this.SelectionStart = base.Text.Length; return; } if (this._dropDownOnly && !string.IsNullOrEmpty(base.Text)) { bool hasValue = false; foreach (object item in this._listBox.Items) { string itemText = this._listBox.GetItemText(item); if (itemText.Contains(this.Text)) { base.Text = itemText; this._listBox.SelectedItem = item; hasValue = true; break; } } if (!hasValue) { base.Text = string.Empty; this._listBox.ClearSelected(); } this.SelectionStart = base.Text.Length; } } /// /// 模糊过滤数据 /// /// private void SetDataSource(string text) { DataTable dtDataSource = this._listBox.DataSource as DataTable; if (dtDataSource == null) { return; } this._listBox.SelectedIndexChanged -= this.ListBox_SelectedIndexChanged; if (string.IsNullOrEmpty(text) || string.IsNullOrEmpty(this._listBox.DisplayMember) || string.IsNullOrEmpty(this._listBox.ValueMember)) { dtDataSource.DefaultView.RowFilter = null; } else { dtDataSource.DefaultView.RowFilter = this._listBox.DisplayMember + " LIKE '%" + Utility.SelectFilterLike(text) + "%'"; } if (string.IsNullOrEmpty(text)) { this._listBox.ClearSelected(); this._listBox.SelectedItem = null; this.TextChanged -= this.DKListBoxComboBox_TextChanged; base.Text = text; this.TextChanged += this.DKListBoxComboBox_TextChanged; } this._listBox.SelectedIndexChanged += this.ListBox_SelectedIndexChanged; } #endregion } }