| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265 |
-
- using System;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Windows.Forms;
- using Dongke.WinForm.Utilities;
- namespace Dongke.WinForm.Controls
- {
- /// <summary>
- /// 标准下拉框控件
- /// </summary>
- [ToolboxBitmap(typeof(ComboBox))]
- public class CmbComboBox : ComboBox, IDKControl, IDataVerifiable, IAsyncControl, IChildNativeWindow
- {
- #region 内部类
- #endregion
- #region 事件声明
- #region HasErrorChanged
- /// <summary>
- /// 当 HasError 属性的值更改时发生。
- /// </summary>
- private static readonly object EventHasErrorChanged = new object();
- /// <summary>
- /// 当 HasError 属性的值更改时发生。
- /// </summary>
- [Description("当 HasError 属性的值更改时发生。"), Category("CustomerEx")]
- public event EventHandler HasErrorChanged
- {
- add
- {
- base.Events.AddHandler(EventHasErrorChanged, value);
- }
- remove
- {
- base.Events.RemoveHandler(EventHasErrorChanged, value);
- }
- }
- /// <summary>
- /// 引发 HasErrorChanged 事件
- /// </summary>
- /// <param name="e">包含事件数据的 EventArgs</param>
- protected virtual void OnHasErrorChanged(EventArgs e)
- {
- EventHandler eventHandler = (EventHandler)base.Events[EventHasErrorChanged];
- if (eventHandler != null)
- {
- eventHandler(this, e);
- }
- }
- #endregion
- #region ReadOnlyChanged
- /// <summary>
- /// 当 ReadOnly 属性的值更改时发生。
- /// </summary>
- private static readonly object EventReadOnlyChanged = new object();
- /// <summary>
- /// 当 ReadOnly 属性的值更改时发生
- /// </summary>
- [Description("当 ReadOnly 属性的值更改时发生。"), Category("CustomerEx")]
- public event EventHandler ReadOnlyChanged
- {
- add
- {
- base.Events.AddHandler(EventReadOnlyChanged, value);
- }
- remove
- {
- base.Events.RemoveHandler(EventReadOnlyChanged, value);
- }
- }
- /// <summary>
- /// 引发 ReadOnlyChanged 事件
- /// </summary>
- /// <param name="e"></param>
- protected virtual void OnReadOnlyChanged(EventArgs e)
- {
- EventHandler eventHandler = base.Events[EventReadOnlyChanged] as EventHandler;
- if (eventHandler != null)
- {
- eventHandler(this, e);
- }
- }
- #endregion
- #region EditReadOnlyChanged
- /// <summary>
- /// 当 EditReadOnly 属性的值更改时发生。
- /// </summary>
- private static readonly object EventEditReadOnlyChanged = new object();
- /// <summary>
- /// 当 EditReadOnly 属性的值更改时发生
- /// </summary>
- [Description("当 EditReadOnly 属性的值更改时发生。"), Category("CustomerEx")]
- public event EventHandler EditReadOnlyChanged
- {
- add
- {
- base.Events.AddHandler(EventEditReadOnlyChanged, value);
- }
- remove
- {
- base.Events.RemoveHandler(EventEditReadOnlyChanged, value);
- }
- }
- /// <summary>
- /// 引发 EditReadOnlyChanged 事件
- /// </summary>
- /// <param name="e"></param>
- protected virtual void OnEditReadOnlyChanged(EventArgs e)
- {
- EventHandler eventHandler = base.Events[EventEditReadOnlyChanged] as EventHandler;
- if (eventHandler != null)
- {
- eventHandler(this, e);
- }
- }
- #endregion
- #endregion
- #region 成员变量
- /// <summary>
- /// 焦点是否进入控件
- /// </summary>
- private bool _entered = false;
- /// <summary>
- /// 鼠标是否进入控件
- /// </summary>
- private bool _mouseOver = false;
- /// <summary>
- /// 边框颜色
- /// </summary>
- private Color? _borderColor = null;
- /// <summary>
- /// 边框样式
- /// </summary>
- private BorderStyle _borderStyle = BorderStyle.Fixed3D;
- /// <summary>
- /// 指示控件中的文本是否为只读
- /// </summary>
- private bool _editReadOnly = true;
- /// <summary>
- /// 指示控件中是否为只读
- /// </summary>
- private bool _readOnly = false;
- /// <summary>
- /// ComboBox内部的Edit
- /// </summary>
- private ChildNativeWindow _childEdit = null;
- private bool _hasNullData = false;
- #endregion
- #region 构造函数
- /// <summary>
- /// 标准复选框列表控件
- /// </summary>
- public CmbComboBox()
- {
- base.FormattingEnabled = false;
- CommonSetting.InitControls(this);
- }
- #endregion
- #region 属性
- /// <summary>
- /// 获取一个值,该值指示控件是否有输入焦点。
- /// </summary>
- [DefaultValue(false)]
- [Browsable(false)]
- [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- [EditorBrowsable(EditorBrowsableState.Advanced)]
- public virtual bool Entered
- {
- get
- {
- return this._entered;
- }
- protected set
- {
- if (this._entered != value)
- {
- this._entered = value;
- this.InvalidateBorder();
- }
- }
- }
- /// <summary>
- /// 获取一个值,该值指示鼠标是否在控件上方。
- /// </summary>
- [DefaultValue(false)]
- [Browsable(false)]
- [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- [EditorBrowsable(EditorBrowsableState.Advanced)]
- public virtual bool MouseOver
- {
- get
- {
- return this._mouseOver;
- }
- protected set
- {
- if (this._mouseOver != value)
- {
- this._mouseOver = value;
- this.InvalidateBorder();
- }
- }
- }
- /// <summary>
- /// 获取或设置控件四周绘制的边框的类型
- /// </summary>
- [Description("获取或设置控件四周绘制的边框的类型。"), Category("CustomerEx")]
- [DefaultValue(BorderStyle.Fixed3D)]
- //[Browsable(false)]
- //[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- //[EditorBrowsable(EditorBrowsableState.Advanced)]
- public virtual BorderStyle BorderStyle
- {
- get
- {
- return this._borderStyle;
- }
- set
- {
- if (!Enum.IsDefined(typeof(BorderStyle), value))
- {
- throw new InvalidEnumArgumentException("value", (int)value, typeof(BorderStyle));
- }
- if (this._borderStyle != value)
- {
- this._borderStyle = value;
- base.UpdateStyles();
- base.RecreateHandle();
- this.InvalidateBorder();
- }
- }
- }
- /// <summary>
- /// 获取或设置一个值,该值指示此控件是否只读。
- /// </summary>
- [Description("获取或设置一个值,该值指示此控件是否只读。"), Category("CustomerEx")]
- [DefaultValue(false)]
- public virtual bool ReadOnly
- {
- get
- {
- return this._readOnly;
- }
- set
- {
- if (this._readOnly != value)
- {
- this._readOnly = value;
- this.SetEditReadOnly();
- this.OnReadOnlyChanged(EventArgs.Empty);
- }
- }
- }
- /// <summary>
- /// 获取或设置一个值,该值指示文本框中的文本是否为只读。
- /// </summary>
- [Description("获取或设置一个值,该值指示文本框中的文本是否为只读。"), Category("CustomerEx")]
- [DefaultValue(true)]
- public virtual bool EditReadOnly
- {
- get
- {
- return this._editReadOnly;
- }
- set
- {
- if (this._editReadOnly != value)
- {
- this._editReadOnly = value;
- this.SetEditReadOnly();
- this.OnEditReadOnlyChanged(EventArgs.Empty);
- }
- }
- }
- /// <summary>
- /// 获取或设置一个值,该值指示是否向数据源中插入null选项(数据源为DataTable)。
- /// </summary>
- [Description("获取或设置一个值,该值指示是否向数据源中插入null选项(数据源为DataTable)。"), Category("CustomerEx")]
- [DefaultValue(false)]
- public virtual bool HasNullData
- {
- get
- {
- return this._hasNullData;
- }
- set
- {
- if (this._hasNullData != value)
- {
- this._hasNullData = value;
- this.SetNullData(this.DataSource, true);
- }
- }
- }
- #endregion
- #region 重写属性
- /// <summary>
- /// 获取或设置控件的数据源
- /// </summary>
- [Description("获取或设置控件的数据源。"), Category("ListControl")]
- [AttributeProvider(typeof(IListSource))]
- [DefaultValue(null)]
- [RefreshProperties(RefreshProperties.Repaint)]
- public new virtual object DataSource
- {
- get
- {
- return base.DataSource;
- }
- set
- {
- this.SetNullData(value, false);
- base.DataSource = value;
- }
- }
- #endregion
- #region 重写事件
- #region 属性改变
- /// <summary>
- /// 句柄创建时
- /// </summary>
- /// <param name="e"></param>
- protected override void OnHandleCreated(EventArgs e)
- {
- base.OnHandleCreated(e);
- if (this._childEdit != null)
- {
- return;
- }
- //if (this.DropDownStyle != ComboBoxStyle.DropDownList)
- //{
- // IntPtr window = WindowsAPI.GetWindow(new HandleRef(this, base.Handle), 5);
- // if (window != IntPtr.Zero)
- // {
- // if (this.DropDownStyle == ComboBoxStyle.Simple)
- // {
- // NativeWindow childListBox = new CmbComboBox.ComboBoxChildEditNativeWindow(this);
- // childListBox.AssignHandle(window);
- // window = WindowsAPI.GetWindow(new HandleRef(this, window), 2);
- // }
- // this._childEdit = new CmbComboBox.ComboBoxChildEditNativeWindow(this);
- // this._childEdit.AssignHandle(window);
- // }
- //}
- IntPtr window = WindowsAPI.FindWindowEx(base.Handle, IntPtr.Zero, "Edit", "");
- this._childEdit = new ChildNativeWindow(this, "Edit");
- this._childEdit.AssignHandle(window);
- this.SetEditReadOnly();
- }
- /// <summary>
- /// 选择项目改变
- /// </summary>
- /// <param name="e"></param>
- protected override void OnSelectedIndexChanged(EventArgs e)
- {
- this.SetDefaultOnCheck();
- base.OnSelectedIndexChanged(e);
- this.ValidateData();
- }
- /// <summary>
- /// 数据源改变事件
- /// </summary>
- /// <param name="e"></param>
- protected override void OnDataSourceChanged(EventArgs e)
- {
- base.OnDataSourceChanged(e);
- }
- #endregion
- #region 行为事件
- #endregion
- #region 键盘事件
- /// <summary>
- /// 键盘点击
- /// </summary>
- /// <param name="e"></param>
- protected override void OnKeyDown(KeyEventArgs e)
- {
- base.OnKeyDown(e);
- if (this._readOnly)
- {
- switch (e.KeyCode)
- {
- case Keys.Up:
- case Keys.Down:
- case Keys.PageUp:
- case Keys.PageDown:
- case Keys.Back:
- case Keys.Delete:
- e.Handled = true;
- break;
- default:
- break;
- }
- return;
- }
- if (this._editReadOnly)
- {
- if (e.KeyCode == Keys.Delete ||
- e.KeyCode == Keys.Back)
- {
- if (!this._mustInput)
- {
- this.ClearValue();
- }
- e.Handled = true;
- return;
- }
- }
- if (this.Items.Count > 0)
- {
- if (e.KeyCode == Keys.Up && this.SelectedIndex < 1)
- {
- this.SelectPrevItem();
- this.SelectAll();
- e.Handled = true;
- return;
- }
- if (e.KeyCode == Keys.Down &&
- (this.SelectedIndex < 1 || this.SelectedIndex == this.Items.Count - 1))
- {
- this.SelectNextItem();
- this.SelectAll();
- e.Handled = true;
- return;
- }
- }
- }
- #endregion
- #region 焦点事件
- /// <summary>
- /// 输入焦点进入控件
- /// </summary>
- /// <param name="e"></param>
- protected override void OnEnter(EventArgs e)
- {
- this.Entered = true;
- base.OnEnter(e);
- }
- /// <summary>
- /// 获得焦点
- /// </summary>
- /// <param name="e"></param>
- protected override void OnGotFocus(EventArgs e)
- {
- base.OnGotFocus(e);
- }
- /// <summary>
- /// 失去焦点
- /// </summary>
- /// <param name="e"></param>
- protected override void OnLostFocus(EventArgs e)
- {
- base.OnLostFocus(e);
- }
- /// <summary>
- /// 输入焦点离开控件
- /// </summary>
- /// <param name="e"></param>
- protected override void OnLeave(EventArgs e)
- {
- base.OnLeave(e);
- //this.Entered = false;
- }
- /// <summary>
- /// 控件正在验证
- /// </summary>
- /// <param name="e"></param>
- protected override void OnValidating(CancelEventArgs e)
- {
- base.OnValidating(e);
- if (this.HasError && !this._canLostFocusOnError)
- {
- e.Cancel = true;
- }
- }
- /// <summary>
- /// 控件完成验证
- /// </summary>
- /// <param name="e"></param>
- protected override void OnValidated(EventArgs e)
- {
- this.Entered = false;
- base.OnValidated(e);
- }
- #endregion
- #region 鼠标事件
- /// <summary>
- /// 鼠标进入控件
- /// </summary>
- /// <param name="e"></param>
- protected override void OnMouseEnter(EventArgs e)
- {
- this.MouseOver = true;
- base.OnMouseEnter(e);
- }
- /// <summary>
- /// 鼠标离开控件
- /// </summary>
- /// <param name="e"></param>
- protected override void OnMouseLeave(EventArgs e)
- {
- base.OnMouseLeave(e);
- this.MouseOver = false;
- }
- /// <summary>
- /// 鼠标移动
- /// </summary>
- /// <param name="e"></param>
- protected override void OnMouseMove(MouseEventArgs e)
- {
- base.OnMouseMove(e);
- }
- /// <summary>
- /// 鼠标按下
- /// </summary>
- /// <param name="e"></param>
- protected override void OnMouseDown(MouseEventArgs e)
- {
- base.OnMouseDown(e);
- }
- /// <summary>
- /// 鼠标抬起
- /// </summary>
- /// <param name="e"></param>
- protected override void OnMouseUp(MouseEventArgs e)
- {
- base.OnMouseUp(e);
- }
- /// <summary>
- /// 鼠标滚轮滚动
- /// </summary>
- /// <param name="e"></param>
- protected override void OnMouseWheel(MouseEventArgs e)
- {
- base.OnMouseWheel(e);
- if (this._readOnly)
- {
- return;
- }
- if (this.DropDownStyle == ComboBoxStyle.Simple &&
- this.Items.Count > 0)
- {
- if (e.Delta > 0)
- {
- this.SelectPrevItem();
- }
- else
- {
- this.SelectNextItem();
- }
- }
- }
- #endregion
- #endregion
- #region 重写方法
- /// <summary>
- /// 处理 Windows 消息
- /// </summary>
- /// <param name="m">要处理的 Windows System.Windows.Forms.Message</param>
- protected override void WndProc(ref Message m)
- {
- if (this._readOnly)
- {
- if (m.Msg == (int)WindowsMessage.WM_LBUTTONDBLCLK ||
- m.Msg == (int)WindowsMessage.WM_LBUTTONDOWN)
- {
- return;
- }
- }
- base.WndProc(ref m);
- if (m.Msg == (int)WindowsMessage.WM_NCDESTROY)
- {
- this.ReleaseChildWindow();
- return;
- }
- if (m.Msg == (int)WindowsMessage.WM_PAINT ||
- m.Msg == (int)WindowsMessage.WM_NCPAINT ||
- m.Msg == (int)WindowsMessage.WM_CTLCOLOREDIT)
- {
- BorderColorPaint.WmBorderPaint(this._borderColor, this.Width, this.Height, ref m);
- return;
- }
- }
- #endregion
- #region 公有方法
- /// <summary>
- /// 初始化显示的值
- /// </summary>
- /// <param name="text"></param>
- /// <param name="value"></param>
- public DataRow InitValue(string text, object value)
- {
- if (this.DataManager == null)
- {
- if (this.Items.Count > 0)
- {
- foreach (object item in this.Items)
- {
- string t = this.GetItemText(item);
- if (t == text)
- {
- this.SelectedItem = item;
- return null;
- }
- }
- }
- this.Items.Insert(0, value);
- this.SelectedIndex = 0;
- //this.Text = text;
- return null;
- }
- DataTable data = this.DataSource as DataTable;
- if (data == null)
- {
- return null;
- }
- if (value == null)
- {
- value = DBNull.Value;
- }
- foreach (DataRow item in data.Rows)
- {
- object v = item[this.ValueMember];
- if (value.Equals(v))
- {
- this.SelectedValue = v;
- return null;
- }
- }
- DataRow row = data.NewRow();
- row[this.ValueMember] = value;
- row[this.DisplayMember] = text + "【停用】";
- if (this.HasNullData)
- {
- data.Rows.InsertAt(row, 1);
- this.SelectedIndex = 1;
- }
- else
- {
- data.Rows.InsertAt(row, 0);
- this.SelectedIndex = 0;
- }
- return row;
- }
- /// <summary>
- /// 选择下一个Item
- /// </summary>
- /// <param name="clearSelect">是否能选择空</param>
- public void SelectNextItem(bool clearSelect = true)
- {
- int boxItemCount = this.Items.Count;
- if (boxItemCount < 1)
- {
- return;
- }
- int boxSelectedIndex = this.SelectedIndex;
- boxSelectedIndex++;
- if (boxSelectedIndex >= boxItemCount)
- {
- if (this._mustInput || !clearSelect || this._hasNullData)
- {
- boxSelectedIndex = 0;
- }
- else
- {
- boxSelectedIndex = -1;
- }
- }
- //if (boxSelectedIndex < 0)
- //{
- // //this.ClearSelected();
- //}
- //else
- {
- this.SelectedIndex = boxSelectedIndex;
- }
- }
- /// <summary>
- /// 选择上一个Item
- /// </summary>
- /// <param name="clearSelect">是否能选择空</param>
- public void SelectPrevItem(bool clearSelect = true)
- {
- int boxItemCount = this.Items.Count;
- if (boxItemCount < 1)
- {
- return;
- }
- int boxSelectedIndex = this.SelectedIndex;
- boxSelectedIndex--;
- if (boxSelectedIndex < -1 ||
- ((this._mustInput || !clearSelect || this._hasNullData) && boxSelectedIndex < 0))
- {
- boxSelectedIndex = boxItemCount - 1;
- }
- //if (boxSelectedIndex < 0)
- //{
- // this.ClearSelected();
- //}
- //else
- {
- this.SelectedIndex = boxSelectedIndex;
- }
- }
- #endregion
- #region 内部方法
- /// <summary>
- /// 处理ComboBox内部Edit的消息
- /// </summary>
- /// <param name="child">Edit</param>
- /// <param name="m">消息</param>
- /// <returns>消息是否已经处理过</returns>
- public virtual bool ChildWndProc(ChildNativeWindow child, ref Message m)
- {
- if (this._editReadOnly || this._readOnly)
- {
- if (m.Msg == (int)WindowsMessage.WM_PASTE)
- {
- WindowsAPI.MessageBeep(BeepType.MB_OK);
- return true;
- }
- if (m.Msg == (int)WindowsMessage.WM_CUT)
- {
- if (this.SelectionLength > 0)
- {
- Clipboard.SetText(this.SelectedText);
- }
- WindowsAPI.MessageBeep(BeepType.MB_OK);
- return true;
- }
- if (m.Msg == (int)WindowsMessage.WM_CHAR)
- {
- int wp = m.WParam.ToInt32();
- // = Cut(0x18)
- if (wp == 0x18)
- {
- if (this.SelectionLength > 0)
- {
- Clipboard.SetText(this.SelectedText);
- }
- WindowsAPI.MessageBeep(BeepType.MB_OK);
- return true;
- }
- // = Copy(0x3) esc(27) enter(13)
- if (wp == 0x3 || wp == 27 || wp == 13)
- {
- return false;
- }
- // back(8)
- else if (wp == 8)
- {
- return this._readOnly;
- }
- else
- {
- WindowsAPI.MessageBeep(BeepType.MB_OK);
- return true;
- }
- }
- }
- if (m.Msg == (int)WindowsMessage.WM_LBUTTONDBLCLK)
- {
- this.OnDoubleClick(EventArgs.Empty);
- }
- return false;
- }
- #endregion
- #region 保护方法
- /// <summary>
- /// 引发 System.Windows.Forms.Control.KeyDown 事件。
- /// </summary>
- /// <param name="e"></param>
- protected virtual void OnComBoxKeyDown(KeyEventArgs e)
- {
- base.OnKeyDown(e);
- }
- /// <summary>
- /// 输入验证时,设定默认值。
- /// </summary>
- protected virtual void SetDefaultOnCheck()
- {
- if (this._mustInput && this.SelectedIndex < 0 && this.Items.Count > 0)
- {
- this.SelectedIndex = 0;
- }
- }
- /// <summary>
- /// 设置文本框只读
- /// </summary>
- protected virtual void SetEditReadOnly()
- {
- this.SetEditReadOnly(this._readOnly || this._editReadOnly);
- }
- #endregion
- #region 私有方法
- /// <summary>
- /// 使父控件的指定区域无效(将其添加到控件的更新区域,下次绘制操作时将重新绘制更新区域),并向父控件发送绘制消息。
- /// </summary>
- private void InvalidateBorder()
- {
- Color? borderColor = BorderColorPaint.GetBorderColor(this as IDataVerifiable, this._entered, this._mouseOver);
- if (borderColor != this._borderColor)
- {
- this._borderColor = borderColor;
- if (this.Parent == null)
- {
- this.Invalidate();
- }
- else
- {
- this.Parent.Invalidate(this.Bounds, true);
- }
- }
- }
- /// <summary>
- /// 释放与此窗口组合Edit关联的句柄
- /// </summary>
- private void ReleaseChildWindow()
- {
- if (this._childEdit != null)
- {
- this._childEdit.ReleaseHandle();
- this._childEdit = null;
- }
- //if (this.childListBox != null)
- //{
- // this.childListBox.ReleaseHandle();
- // this.childListBox = null;
- //}
- }
- private void SetNullData(object dataSource, bool canRemove)
- {
- System.Data.DataTable dt = dataSource as System.Data.DataTable;
- if (dt == null)
- {
- return;
- }
- if (this._hasNullData)
- {
- dt.Rows.InsertAt(dt.NewRow(), 0);
- }
- else if (canRemove)
- {
- dt.Rows.RemoveAt(0);
- }
- }
- /// <summary>
- /// 设置文本框只读
- /// </summary>
- /// <param name="readOnly"></param>
- protected void SetEditReadOnly(bool readOnly)
- {
- if (this._childEdit != null)
- {
- WindowsAPI.SendMessage(this._childEdit.Handle, (int)WindowsMessage.EM_SETREADONLY,
- readOnly ? -1 : 0, 0);
- }
- }
- #endregion
- #region IDataVerifiable 成员
- #region 成员变量
- /// <summary>
- /// 显示边框颜色
- /// </summary>
- private bool _showBorderColor = true;
- /// <summary>
- /// 控件的项目名
- /// </summary>
- private string _itemName = null;
- /// <summary>
- /// 控件是否是必须输入项目
- /// </summary>
- private bool _mustInput = false;
- /// <summary>
- /// 控件在验证输入错误时,如何提示
- /// </summary>
- private InputErrorAlert _errorAlert = InputErrorAlert.Validated;
- /// <summary>
- /// 是否显示必须输入项目的提示
- /// </summary>
- private bool _showMustInputAlert = true;
- /// <summary>
- /// 验证不通过时,焦点能否离开
- /// </summary>
- private bool _canLostFocusOnError = true;
- /// <summary>
- /// 验证是否有错误
- /// </summary>
- private bool _hasError = false;
- /// <summary>
- /// 是否自定义错误
- /// </summary>
- private bool _hasCustomerError = false;
- /// <summary>
- /// 错误编码
- /// </summary>
- private ControlErrorCode _errorCode = ControlErrorCode.DKC_0000;
- /// <summary>
- /// 错误消息
- /// </summary>
- private string _errorMessage = null;
- /// <summary>
- /// 自定义错误消息
- /// </summary>
- private string _customerErrorMessage = null;
- #endregion
- #region 属性
- /// <summary>
- /// 获取或设置控件是否显示边框颜色。
- /// </summary>
- [Description("获取或设置控件是否显示边框颜色。"), Category("IDataVerifiable")]
- [DefaultValue(true)]
- public bool ShowBorderColor
- {
- get
- {
- return this._showBorderColor;
- }
- set
- {
- if (this._showBorderColor != value)
- {
- this._showBorderColor = value;
- this.InvalidateBorder();
- }
- }
- }
- /// <summary>
- /// 获取或设置控件的项目名
- /// </summary>
- [Description("获取或设置控件的项目名。"), Category("IDataVerifiable")]
- [DefaultValue(null)]
- public string CDItemName
- {
- get
- {
- return this._itemName;
- }
- set
- {
- this._itemName = value;
- }
- }
- /// <summary>
- /// 获取或设置控件是否必须选中项目。
- /// </summary>
- [Description("获取或设置控件是否必须选中项目。"), Category("IDataVerifiable")]
- [DefaultValue(false)]
- public virtual bool MustInput
- {
- get
- {
- return this._mustInput;
- }
- set
- {
- if (this._mustInput != value)
- {
- this._mustInput = value;
- this.ValidateData();
- if (value && this._showMustInputAlert)
- {
- this.InvalidateBorder();
- }
- }
- }
- }
- /// <summary>
- /// 获取或设置控件是否必须选中项目。
- /// </summary>
- [Description("获取或设置控件在验证输入错误时,如何提示。"), Category("IDataVerifiable")]
- [DefaultValue(typeof(InputErrorAlert), "Validated")]
- public InputErrorAlert InputErrorAlert
- {
- get
- {
- return this._errorAlert;
- }
- set
- {
- if (this._errorAlert != value)
- {
- this._errorAlert = value;
- this.InvalidateBorder();
- }
- }
- }
- /// <summary>
- /// 获取或设置控件是否显示必须输入项目提示
- /// </summary>
- [Description("获取或设置控件是否显示必须输入项目提示。"), Category("IDataVerifiable")]
- [DefaultValue(true)]
- public bool ShowMustInputAlert
- {
- get
- {
- return this._showMustInputAlert;
- }
- set
- {
- if (this._showMustInputAlert != value)
- {
- this._showMustInputAlert = value;
- this.InvalidateBorder();
- }
- }
- }
- /// <summary>
- /// 获取或设置当验证不通过时,控件是否可以失去焦点
- /// </summary>
- [Description("获取或设置当验证不通过时,控件是否可以失去焦点。"), Category("IDataVerifiable")]
- [DefaultValue(true)]
- public bool CanLostFocusOnError
- {
- get
- {
- return this._canLostFocusOnError;
- }
- set
- {
- this._canLostFocusOnError = value;
- }
- }
- /// <summary>
- /// 获取控件校验时是否有错误
- /// </summary>
- [Description("获取控件校验时是否有错误。"), Category("IDataVerifiable")]
- [DefaultValue(false)]
- public bool HasError
- {
- get
- {
- return this._hasCustomerError || this._hasError;
- }
- }
- /// <summary>
- /// 获取控件校验时的错误编码
- /// </summary>
- [Description("获取控件校验时的错误编码。"), Category("IDataVerifiable")]
- [DefaultValue(typeof(ControlErrorCode), "DKC_0000")]
- public ControlErrorCode ErrorCode
- {
- get
- {
- return this._hasCustomerError ? ControlErrorCode.DKC_C001 : this._errorCode;
- }
- }
- /// <summary>
- /// 获取控件校验时的错误消息
- /// </summary>
- [Description("获取控件校验时的错误编码。"), Category("IDataVerifiable")]
- [DefaultValue(null)]
- public string ErrorMessage
- {
- get
- {
- return this._hasCustomerError ? this._customerErrorMessage : this._errorMessage;
- }
- }
- #endregion
- #region 公有方法
- /// <summary>
- /// 设置自定义错误
- /// </summary>
- /// <param name="hasError">输入是否有错误</param>
- /// <param name="errorMessage">错误消息</param>
- public virtual void SetCustomerError(bool hasError, string errorMessage)
- {
- if (this._hasCustomerError != hasError ||
- this._customerErrorMessage != errorMessage)
- {
- this._hasCustomerError = hasError;
- this._customerErrorMessage = errorMessage;
- this.OnHasErrorChanged(EventArgs.Empty);
- this.InvalidateBorder();
- }
- }
- /// <summary>
- /// 清除自定义错误
- /// </summary>
- public virtual void ClearCustomerError()
- {
- this.SetCustomerError(false, null);
- }
- /// <summary>
- /// 验证输入内容
- /// </summary>
- /// <returns>验证结果</returns>
- public virtual bool ValidateData()
- {
- if (this._mustInput && this.SelectedIndex < 0)
- {
- this.SetError(true, ControlErrorCode.DKC_0001, this._itemName);
- return false;
- }
- this.ClearError();
- return true;
- }
- /// <summary>
- /// 清除输入项
- /// </summary>
- public virtual void ClearValue()
- {
- this.Text = null;
- this.SelectedIndex = -1;
- }
- #endregion
- #region 保护方法
- /// <summary>
- /// 设置验证不通过错误
- /// </summary>
- /// <param name="hasError">是否有错误</param>
- /// <param name="code">错误编码</param>
- /// <param name="args">设置格式的对象</param>
- protected void SetError(bool hasError, ControlErrorCode code, params object[] args)
- {
- if (this._hasError != hasError ||
- this._errorCode != code)
- {
- this._hasError = hasError;
- this._errorCode = code;
- if (args != null && args.Length > 0)
- {
- this._errorMessage = string.Format(code.GetDescription(), args);
- }
- else
- {
- this._errorMessage = code.GetDescription();
- }
- this.OnHasErrorChanged(EventArgs.Empty);
- this.InvalidateBorder();
- }
- }
- /// <summary>
- /// 清除验证不通过错误
- /// </summary>
- protected void ClearError()
- {
- this.SetError(false, ControlErrorCode.DKC_0000);
- }
- #endregion
- #endregion
- #region IAsyncControl 成员
- #region 成员变量
- /// <summary>
- /// 异步处理开始时,控件状态
- /// </summary>
- private bool _asyncBeginStatus = false;
- private bool _asyncBeginFocused = false;
- #endregion
- #region 公有方法
- /// <summary>
- /// 开始异步处理
- /// </summary>
- /// <param name="doFocus">是否处理焦点</param>
- public virtual void BeginAsync(ref bool doFocus)
- {
- this._asyncBeginFocused = false;
- if (doFocus && this.Focused)
- {
- this._asyncBeginFocused = true;
- doFocus = false;
- }
- this._asyncBeginStatus = this.ReadOnly;
- this.ReadOnly = true;
- }
- /// <summary>
- /// 结束异步处理
- /// </summary>
- public virtual void EndAsync()
- {
- this.ReadOnly = this._asyncBeginStatus;
- if (this._asyncBeginFocused)
- {
- this.Focus();
- }
- }
- #endregion
- #endregion
- }
- }
|