/*******************************************************************************
* 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
}
}