我想要一个文本框,允许其中的某些文本“不变”且不可编辑,而文本的其余部分是可编辑的。例如,我想定义一个这样的模板:
<Name:>[]
<Address:>[] <City>:[]
以便用户稍后可以输入:
<Name:>[Stefan]
<Address:>[Nowhere] <City>:[Alaska]
但不是:
<I'm typing here lol:>[Stefan]
<Address:>[Nowhere] <State>:[Alaska]
理想情况下,他们甚至无法将光标置于&lt;&gt;之间,类似于Microsoft Word模板。
有什么想法吗?屏蔽的文本框控件似乎沿着正确的路径,但不是多线,并且不允许您在大括号之间输入可变数量的字符。例如。
提前致谢。
答案 0 :(得分:3)
我不知道任何现成的组件。但你可以试试这个简单的方法。
(.*)
或([a-z]*)
或其他任何您希望用户添加文本的模板。然后,您可以使用相同的正则表达式从文本框中提取数据。
您甚至可以使用RichTextBox并使用正则表达式执行格式化。
更新以下是我写的内容。它似乎有效:
[DefaultProperty("Regex")]
public partial class MaskedEdit : UserControl
{
private Regex regex = new Regex("");
private bool myChange = false;
private string goodText;
private Font dataFont;
public MaskedEdit()
{
myChange = true;
InitializeComponent();
myChange = false;
dataFont = new Font(Font, FontStyle.Bold);
goodText = Text;
}
[Editor("System.ComponentModel.Design.MultilineStringEditor, System.Design", typeof(UITypeEditor)), Localizable(true)]
[DefaultValue("")]
public String Regex
{
get { return regex.ToString(); }
set
{
if (value != null)
{
regex = new Regex(value);
}
}
}
[EditorBrowsable(EditorBrowsableState.Always)]
[Browsable(true)]
[Editor("System.ComponentModel.Design.MultilineStringEditor, System.Design", typeof(UITypeEditor)), Localizable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override string Text
{
get { return rtf.Text; }
set {
int selSt = rtf.SelectionStart;
int selLen = rtf.SelectionLength;
rtf.Text = value;
rtf.SelectionStart = selSt;
rtf.SelectionLength = selLen;
}
}
private void rtf_TextChanged(object sender, EventArgs e)
{
if (myChange) return;
Match m = regex.Match(Text);
if (m.Success)
{
goodText = Text;
Colorize(m);
}
else
{
myChange = true;
Text = goodText;
myChange = false;
m = regex.Match(Text);
if (m.Success)
{
Colorize(m);
}
}
}
public IEnumerable<string> Data
{
get
{
Match m = regex.Match(Text);
bool first = true;
foreach (Group g in m.Groups)
{
if (first) { first = false; continue; }
yield return Text.Substring(g.Index, g.Length);
}
}
}
private void Colorize(Match m)
{
int selSt = rtf.SelectionStart;
int selLen = rtf.SelectionLength;
rtf.SelectionStart = 0;
rtf.SelectionLength = rtf.TextLength;
rtf.SelectionFont = Font;
bool first = true;
foreach (Group g in m.Groups)
{
if (first) { first = false; continue; }
rtf.SelectionStart = g.Index;
rtf.SelectionLength = g.Length;
rtf.SelectionFont = dataFont;
}
rtf.SelectionStart = selSt;
rtf.SelectionLength = selLen;
}
private void MaskedEdit_FontChanged(object sender, EventArgs e)
{
dataFont = new Font(Font, FontStyle.Bold);
}
}
答案 1 :(得分:1)
我建议使用多个控件而不是一个。单个文本框将要求用户将光标移动到下一个字段,而多个控件将允许用户在字段之间进行选项卡,这是预期的行为。如果你想让它像一个控件一样看起来(也许是为了使它看起来像地址标签或其他东西),你可以使用无边框文本框并将标签和文本框全部放在一个有一个控件的面板中。边框和SystemColors.Window
背景。为了获得额外的效果,可以在每个文本框下方放置线条,这可以通过带有BorderStyle.FixedSingle
边框的1像素高标签轻松完成。