ColoredErrorProvider:自定义扩展提供程序,基于ErrorProvider类。





4.00/5 (6投票s)
2004年1月22日
4分钟阅读

50740

1461
通过闪烁控件的背景色来指示控件内的错误。
引言
ColoredErrorProvider
是一个自定义的扩展提供程序。与ErrorProvider
组件一样,此类可用于向用户发出无效数据的警告。
扩展提供程序
扩展提供程序允许您在不创建额外类的情况下扩展控件。
ToolTip扩展提供程序
.NET中的ToolTip
控件是一个扩展提供程序。我们不必为按钮、标签、文本框等每个控件都设置一个ToolTip
属性,而是可以使用ToolTip
类来为其设置提示信息,如下所示:
ToolTip toolTip1 = new ToolTip();
toolTip1.SetToolTip(this.label1, "This is a label");
toolTip1.SetToolTip(this.button1, "this is a button");
ErrorProvider扩展提供程序
ErrorProvider
是一个非常不错的控件,它允许您在控件中的数据无效时,在控件旁边显示一个错误图标。考虑到替代方案是弹出错误对话框、显示状态栏错误或在处理过程中进行验证,这非常方便。
- 弹出错误对话框
- 显示状态栏错误
- 允许在处理过程中进行验证。
此示例中的类与ErrorProvider
类类似。不同之处在于,通过闪烁控件的背景色向用户指示错误/警告。我写这个是因为使用ErrorProvider
必须显示的图标无法放置在任何方便的位置;图标会覆盖其他控件或超出窗体的边界。当然,这也是为了学习如何编写扩展提供程序。
示例
该示例包含一个包含几个组件的小程序,演示了此类用法。单击“Toggle Error”按钮可在分组框内的控件上设置/取消设置错误。TextBox3
已验证。如果其包含的字符数超过10个,则会设置错误。更改此文本字段中的字符数并将其焦点移开,即可看到ColoredErrorProvider
类的效果。
用法
创建ColoredErrorProvider
时,可以指定:
blinkCount
:控件闪烁的次数,之后会稳定在稳定颜色。blinkInterval
:每次闪烁之间的时间(以毫秒为单位)。
设置错误时,可以指定:
control
:必须应用错误的Control
。value
:如果不为空,则控件会闪烁。如果为空,则不显示错误。与ErrorProvider
不同,字符串本身不会显示给用户。blinkColor
:控件闪烁时的背景颜色。blinkCount
:控件闪烁的次数,之后会稳定在稳定颜色。settleColor
:闪烁结束后控件的背景颜色。
代码演练
Form1
类是示例应用程序窗体。我不会详细讲解这段代码。
ColoredErrorProvider
扩展了Control
并实现了IExtenderProvider
,这是实现自己的扩展提供程序所必需的。MSDN表示“提供扩展属性的任何组件都必须实现IExtenderProvider
。然后,可视化设计器可以调用CanExtend
来确定容器中的哪些对象应该接收扩展属性”。由于Control
类的所有派生类都将具有BackColor
属性,因此我们重写了CanExtend
方法,如果对象是Control
,则返回true
。
bool IExtenderProvider.CanExtend(object target)
{
if (target is Control)
{
return true;
}
return false;
}
为了保留已提供ColoredError
的各个控件,我实例化了一个HashTable
。HashTable
的键是控件,值是BlinkControlDetails
结构,其中包含与该控件关联的ColoredError
的详细信息。
private Hashtable originalControlColors = new Hashtable();
struct BlinkControlDetails
{
public Color OriginalBackColor;
public Color BlinkBackColor;
public Color SettleBackColor;
public string ErrorString;
private int[] BlinkCountArray;
...
}
BlinkCountArray
是一个权宜的变通方法。我不知道如何更改结构中作为HashTable
的键的值返回的原始类型的值。如果有人能告诉我一种更好的方法,那就太好了。BlinkCountArray
只有一个条目。这是通过公共属性BlinkCount
间接操作的。
当在ColoredErrorProvider
上调用SetError
时:
- 我根据长度检查是要设置还是移除错误。如果要移除,则将背景色设置为原始颜色,然后将其从
HashTable
中移除。 - 如果是新的,则创建具有适当条目的新
BlinkControlDetails
并将其添加到HashTable
。我们还启用计时器,以便使控件的背景色闪烁。
public void SetError(Control control,
string value, Color blinkColor, int blinkCount, Color settleColor)
{
if (value == null)
{
value = string.Empty;
}
if (value.Length == 0)
{
if (this.originalControlColors.ContainsKey(control))
{
control.BackColor = ((BlinkControlDetails)
this.originalControlColors[control]).OriginalBackColor;
this.originalControlColors.Remove(control);
}
control.Invalidate();
}
else
{
BlinkControlDetails bcd = new BlinkControlDetails(value,
control.BackColor, blinkColor, settleColor, blinkCount*2-1);
this.originalControlColors.Add(control, bcd);
control.BackColor = blinkColor;
control.Invalidate();
if (!this.timer.Enabled)
{
this.timer.Enabled = true;
}
}
}
创建类时,我创建了一个计时器实例。当调用SetError
时,计时器会被启用。
private Timer timer = new Timer();
当计时器滴答时,它会调用OnTimerTick
方法。
private void OnTimerTick(Object myObject, EventArgs myEventArgs)
{
bool atLeastOneBlinked = false;
foreach (Control c in this.originalControlColors.Keys)
{
BlinkControlDetails bcd =
(BlinkControlDetails)this.originalControlColors[c];
if (bcd.BlinkCount>=1)
{
if (c.BackColor.Equals(bcd.OriginalBackColor))
{
c.BackColor = bcd.BlinkBackColor;
}
else if (c.BackColor.Equals(bcd.BlinkBackColor))
{
c.BackColor = bcd.OriginalBackColor;
}
bcd.BlinkCount--;
atLeastOneBlinked = true;
}
else if(bcd.BlinkCount==0)
{
c.BackColor = bcd.SettleBackColor;
bcd.BlinkCount--;
atLeastOneBlinked = true;
}
else
{
continue;
}
c.Invalidate();
}
if (!atLeastOneBlinked)
{
this.timer.Enabled = false;
}
}
我们循环遍历HashTable
中的控件,该哈希表包含已设置错误提供程序的控件。对于每个控件,我们将其背景色在原始背景色和闪烁背景色之间切换。每次闪烁时,我们都会递减闪烁计数。一旦闪烁计数达到0,我们将背景色设置为settleColor
。稳定颜色会告知用户存在问题,而不会因闪烁而打扰他们。
变量atLeastOneBlinked
设置为true
,如果至少有一个控件需要闪烁。如果不需要,我们可以禁用计时器。