如何继承基本文本框以提供彩色边框

时间:2010-02-11 14:27:44

标签: c# winforms user-interface .net-3.5 controls

我有一个winform应用程序,我们在内部使用。它在每个25“页面”(用户控件)上有许多单独的控件。我们的用户群更喜欢非常技术性的应用......他们希望TextBox在需要的字段中被标记为蓝色(如果输入数据,颜色应该消失)。他们希望TextBox更改为绿色,如果已更改数据以提醒他们保存。他们希望将当前突出显示的TextBox概述为RedOrange。

我一直试图从许多不同的角度来看待这个问题(你们中的一些人最近可能看到过类似的帖子)。它们不起作用......所以我知道的一种方法是为每个控件注册paint事件并检查所需部分的“必需”标记。当前字段部分的OnFocus,最后是数据更改部分的Validate事件。

我知道这不是最好的方式,或者至少我强烈怀疑它不是,但我已经没时间了,差不多,接近我的挫折感。话虽如此,那会破坏我的应用程序的响应能力吗?有没有更好的办法?我可以覆盖基本控件以在不同的场所着色,这样我就不必去100个控件中的每一个吗?

任何想法都会受到欢迎,因为我介于我的愚蠢的Paint_Event想法和重写WPF中的所有控件之间......:)

我会奖励一个对我有用的解决方案,并且我很快就可以通过Bounty实施。

我很讨厌颜色......


以下是基于建议的尝试。

public class MyTextBox : TextBox
{
    private bool _isRequired;
    public bool isRequired
    {
        get
        {
            return _isRequired;
        }
        set
        {
            _isRequired = value;
        }
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        if (isRequired && base.Text.Equals(string.Empty))
        {
            HighlightControl(e.Graphics);
        }
    }

    private void HighlightControl(Graphics graphics)
    {
        ControlPaint.DrawBorder(
                graphics,
                this.ClientRectangle,
                Properties.Settings.Default.RequiredFieldColor,
                Properties.Settings.Default.BorderWidth,
                Properties.Settings.Default.BorderStyle,
                Properties.Settings.Default.RequiredFieldColor,
                Properties.Settings.Default.BorderWidth,
                Properties.Settings.Default.BorderStyle,
                Properties.Settings.Default.RequiredFieldColor,
                Properties.Settings.Default.BorderWidth,
                Properties.Settings.Default.BorderStyle,
                Properties.Settings.Default.RequiredFieldColor,
                Properties.Settings.Default.BorderWidth,
                Properties.Settings.Default.BorderStyle);
    }
}

3 个答案:

答案 0 :(得分:4)

我不知道您的应用程序的详细信息,但您可以从基础TextBox中获取自己的控件,并让它为您处理大部分内容。一些想法:

  • 给它一个bool必需属性和一些相应颜色的内部逻辑。

  • 让文本框自行响应 事件 - 输入文本时,它可以 做正确的事 - 改变颜色或 什么是合适的。

  • 为您的派生控件提供 用于设置获取颜色的属性 用于每个条件,然后你就可以 当用户轻松切换它们 决定他们想要粉红色而不是 绿色。

  • 你可以利用焦点事件“知道”你的TextBox(这是你提到的那个控件,所以我假设这是这里使用的主控件)有焦点或丢失它并且文本改变事件可用于驱动控件的所有颜色更改。

  • 你当然可以连接所有的 文本框来控制 应用/确定/任何按钮 确定按钮是否应该是 启用,假设您有一个应用按钮或类似的东西存储点击数据。有很多方法可以沟通。迭代控件并询问他们的状态很容易。

似乎这样可以正常工作。
你有什么尝试?你没有真正提到你尝试过的那些无效的东西。

答案 1 :(得分:4)

你遇到了问题,TextBox是,呃,特别的。 Windows窗体将所有绘制保留到本机Windows EDITBOX控件,不会引发Paint事件。可以通过将UserPaint控件样式设置为true来修复:

using System;
using System.Drawing;
using System.Windows.Forms;

class MyTextBox : TextBox {
  public MyTextBox() {
    this.SetStyle(ControlStyles.UserPaint, true);
  }
  protected override void OnPaint(PaintEventArgs e) {
    base.OnPaint(e);
    // Paint something
    //...
  }
}

将其复制并粘贴到新类中,从工具箱顶部编译并删除新控件。尝试一下,你会很失望的。你所看到的是近20年的appcompat hacks在一个可以追溯到Windows版本2的控件上的结果.EDITBOX提交的一个严重的罪行是在不生成WM_PAINT消息的情况下绘制自己。当Windows必须在386SUX上运行时,这是重要的方式,保持它与旧程序兼容,防止微软修复其行为。

这里没有满意的答案,你必须放弃定制边框的想法。您可以做的是在控件具有焦点时为控件提供不同的BackColor。例如:

class MyTextBox : TextBox {
  Color mBackColor;
  protected override void OnEnter(EventArgs e) {
    mBackColor = base.BackColor;
    base.BackColor = Color.AliceBlue;
    base.OnEnter(e);
  }
  protected override void OnLeave(EventArgs e) {
    base.BackColor = mBackColor;
    base.OnLeave(e);
  }
}

答案 2 :(得分:3)

您可以从基本控件类继承并添加自己的绘图逻辑。这在性能方面不会非常昂贵,但是,如果您的应用程序具有相当大的规模,则必须使用您自己的实现替换每个标准TextBox的出现。