繁体   English   中英

C#中的多行模板文本控件

[英]Multiline Template Text Control in C#

我想要一个文本框,该框允许其中的某些文本“恒定”且不可编辑,而其余文本可编辑。 例如,我想定义一个这样的模板:

<Name:>[]
<Address:>[] <City>:[]

这样用户以后可以输入:

<Name:>[Stefan]
<Address:>[Nowhere] <City>:[Alaska]

但不是:

<I'm typing here lol:>[Stefan]
<Address:>[Nowhere] <State>:[Alaska]

理想情况下,类似于Microsoft Word模板,他们甚至无法将光标置于<>之间。

有任何想法吗? 蒙版的文本框控件似乎沿正确的路径,但是不是多行的,并且不允许您在括号之间输入可变数量的字符。

提前致谢。

我不知道任何现成的组件。 但是您可以尝试这种简单的方法。

  1. 创建一个普通的多行文本框控件
  2. 创建一个基于正则表达式的模板,该模板具有(.*)([az]*)或任何您希望用户在其中添加文本的位置。
  3. 无论何时更改文本,请检查其是否仍与正则表达式匹配。 如果这样,接受香脂。 如果不是,请拒绝更改。

然后,您可以使用相同的正则表达式从文本框中提取数据。

您甚至可以使用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);
    }
}

我建议使用多个控件而不是一个。 单个文本框将要求用户将光标移至下一个字段,而多个控件将允许用户在各字段之间切换,这是预期的行为。 如果要使其看起来像一个控件(可能使其看起来像地址标签之类),则可以使用无边界文本框,并将标签和文本框全部置于具有边框和SystemColors.Window背景的面板中。 。 为了获得额外的效果,最好在每个文本框的下方放置线条,这很容易用带有BorderStyle.FixedSingle边框的1像素高标签来完成。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM