带衬垫的文本框控件






2.33/5 (3投票s)
2007年3月28日
3分钟阅读

78235

1014
一个向富文本框控件添加新属性的用户控件。
引言
文本框控件缺少的一个属性是填充属性,我已经通过这个用户控件添加了它。这允许您在实际文本周围放置边框,这可以改善文本框的外观。边框颜色可能与文本背景颜色不同,在这种情况下,它充当文本的“框架”,如上例所示,或者它可以是相同的颜色,在这种情况下,它充当边距。
背景
创建此效果相对容易,MSDN 提供了一些使用文本框和面板执行此操作的示例。但是,我更愿意创建一个具有此属性的控件,然后能够重复使用它,而不必每次都重新发明轮子。毕竟,这不正是用户控件的用途吗?在这种情况下,我已将一个富文本框放置在用户控件表面上,该表面充当“面板”(就像您要按照 MSDN 的方式进行操作一样)。
用户控件代码
public partial class PTextBox : UserControl
{
/// <summary>
/// PTextBox is a simple user control which provides the missing "Padding"
/// property to a rich text box. This allows the user to define a border
/// around the text. This border can be the same color as the text box
/// in which case it is simply an inner padding or it can be a true border
/// of a different color.
/// <remarks>
/// The two properties of import are the padding size and the background
/// color of the control which acts as the border color for the text box.
/// The rich text box itself is exposed via the "rtb" control which is
/// public.
/// </remarks>
/// </summary>
public PTextBox()
{
InitializeComponent();
}
/// <summary>
/// This property allows the user to set the background color
/// of the rich text box at design time.
/// </summary>
[
Browsable(true),
CategoryAttribute("Appearance"),
Description("The background color of the rich text box.")
]
public Color TextBackColor
{
get
{
return rtb.BackColor;
}
set
{
rtb.BackColor = value;
}
}
/// <summary>
/// This property allows the user to set the foreground color
/// of the rich text box at design time.
/// </summary>
[
Browsable(true),
CategoryAttribute("Appearance"),
Description("The foreground color of the rich text box.")
]
public Color TextForeColor
{
get
{
return rtb.ForeColor;
}
set
{
rtb.ForeColor = value;
}
}
/// <summary>
/// This property allows the user to set the text property
/// of the textbox directly without having to use the "rtb" property.
/// </summary>
[
Browsable(true),
CategoryAttribute("Data"),
Description("The text of the rich text box.")
]
public override string Text
{
get
{
return rtb.Text;
}
set
{
rtb.Text = value;
}
}
/// <summary>
/// The ToString() value of the rich text box.
/// </summary>
/// <returns></returns>
public override string ToString()
{
return rtb.ToString();
}
}
使用代码
首先编译控件,并将生成的 dll 放入您选择的文件夹中,最好是包含您可重用程序集的文件夹。
打开工具箱。右键单击并选择“选择项目”。在“选择工具箱项目”对话框中,浏览到 *PaddedTextBox.dll* 并将其选中用于您的项目。现在,您可以像对待内置的富文本框一样对待此控件,并具有一些附加属性。在属性窗口中,我公开了富文本框的 `Text` 属性,并添加了 `TextForeColor` 和 `TextBackColor` 属性。实际的 `ForeColor` 和 `BackColor` 属性现在应用于用户控件,即边框颜色,尽管在这种情况下,`ForeColor` 毫无意义。我还将富文本框命名为 rtb,将其设为 public,因此您可以在程序中完全控制它,如果您需要访问或更改任何其他属性或捕获任何事件。
下面的演示代码显示了如何使用该控件。为了简化操作,我创建了对富文本框的单独引用,这样我就不必一直通过 `ptb.rtb` 来引用它。在这种情况下,`ptb.TextBackColor` 和 `rtb.BackColor` 指的是同一属性。
using System;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace Test
{
public partial class Form1 : Form
{
private RichTextBox rtb;
private byte clickType = 0;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// Use "rtb" to access the text box within the user control:
rtb = ptb.rtb;
rtb.Font = new Font("Tahoma", 12, FontStyle.Bold);
// Note that we could also use rtb.Text here since they are essentially
// the same:
ptb.Text = "Click to change the text box background color.\r\n\r\n" +
"Double click to change the border color.\r\n\r\n" +
"Use the horizontal slider below to change the border size.\r\n\r\n" +
"Padding = ";
// Set up traps for the text box events that you want to handle
rtb.Click += new System.EventHandler(this.rtb_Click);
rtb.DoubleClick += new System.EventHandler(this.rtb_DoubleClick);
rtb.KeyDown += new System.Windows.Forms.KeyEventHandler(this.rtb_KeyDown);
szBorder.Value = ptb.Padding.All;
SetPadding();
timer1.Interval = 500;
timer1.Enabled = true;
}
/// <summary>
/// Click to change the text box background color
/// </summary>
private void rtb_Click(object sender, EventArgs e)
{
clickType = 1;
rtb.SelectionLength = 0; // Prevent the click from causing a selection
}
/// <summary>
/// Double click to change the border color
/// </summary>
private void rtb_DoubleClick(object sender, EventArgs e)
{
clickType = 2;
rtb.SelectionLength = 0; // Prevent the click from causing a selection
}
/// <summary>
/// We use the timer to allow a doubleclick to be handled without first
/// generating a single click event.
/// </summary>
private void timer1_Tick(object sender, EventArgs e)
{
timer1.Enabled = false;
if (clickType == 1)
{
DialogResult dr = this.colorDialog1.ShowDialog();
if (dr == DialogResult.OK) ptb.TextBackColor = this.colorDialog1.Color;
}
else if (clickType == 2)
{
DialogResult dr = this.colorDialog1.ShowDialog();
if (dr == DialogResult.OK) ptb.BackColor = this.colorDialog1.Color;
}
clickType = 0;
timer1.Enabled = true;
}
/// <summary>
/// You can trap key presses here. This text box should be read-only
/// so we don't allow any keystrokes in it.
/// </summary>
private void rtb_KeyDown(object sender, KeyEventArgs e)
{
e.SuppressKeyPress = true;
e.Handled = true; // This isn't required
}
private void szBorder_Scroll(object sender, ScrollEventArgs e)
{
SetPadding();
}
private void Form1_Resize(object sender, EventArgs e)
{
SetPadding();
}
/// <summary>
/// The scroll bar returns values between 0 and 100 inclusive. Use that value
/// as a percentage of half the smallest of the height and width to determine
/// the border padding. Note that the padding is uniform and does NOT
/// reflect any difference between the height and width.
/// </summary>
private void SetPadding()
{
ptb.Padding = new Padding(Convert.ToInt32(szBorder.Value * .005 *
(this.Width > this.Height ? this.Height : this.Width)));
int i = rtb.Text.IndexOf("Padding =");
rtb.Text = rtb.Text.Substring(0, i) + "Padding = " + ptb.Padding.All.ToString();
}
}
}
关注点
这是一个小谜题。我不确定是否有不需要使用反射的简单解决方案,但我很乐意听取意见。考虑用户控件的 `BackColor` 属性。理想情况下,我希望该属性和 `ForeColor` 属性设置富文本框的同名属性,而不是用户控件面板。然后,您可以添加一个 `BorderColor` 属性来设置控件本身的背景颜色。问题是,当您实现 `BorderColor` 时,它必须引用 `BackColor` 属性,但该属性已被重新定义为设置文本框背景颜色,因此,它不会设置您想要的背景。
历史
- 版本 1.0.0 – 2007 年 7 月 26 日