具有不可编辑单词(标签)的文本框

4

我正在尝试为我的邮件发送应用程序构建模板编辑模块。 目前它看起来像这样:

enter image description here

右侧是可用变量列表,当我发送电子邮件时,这些变量将被替换为正确的值。

现在,当我双击列表项时,我会将右侧列表中的单词添加到模板中:

private void variablesLB_DoubleClick(object sender, EventArgs e)
    {
        var insert = variablesLB.SelectedItem.ToString();
        var index = templateContentTB.SelectionStart;
        templateContentTB.Text = templateContentTB.Text.Insert(index, insert);
        templateContentTB.SelectionStart = index + insert.Length;
        templateContentTB.Focus();
    }

所有这些都很好用,但我无法防止用户手动更改关键字,因此他可以将光标放在«Email»内并将其更改为«Emaail»

例如,在水晶报告中,在将数据库字段放入文本字段后,我能够选择整个名称,并通过按退格键来删除整个名称。

我知道WinForms TextBox内部没有构建此功能,并且我找不到任何可以执行此操作的组件,所以我决定在这里提问,也许有人需要相同的功能或者能够指导我如何实现它。

总而言之,我需要能够在文本框中添加标签,文本框应将此标签视为整体-可选择、可移动且用户应该能够删除它但不能编辑它。


我不知道您使用哪种控件来显示姓名、姓氏、电子邮件等信息。但是,难道没有一个名为 IsReadOnly 的标志吗?您可以将其设置为 True - user3596113
首先的想法是:使用 RichTextBox 和一些自定义对象(图片?)来实现标签。另一个可能性是将标签作为文本更改(也是 RichTextBox),以便用户看到他是否“破坏”了某些内容。由于用户被允许编辑文本,也许您可以向他展示一个完整的文本?其中 <Name> 已经被替换为例如 John - Sinatr
请查看http://www.codeproject.com/Tips/789293/Creating-a-Tagging-System-using-ASP-net-implementi - husnain_sys
你可以编写几十行代码来检查当前输入的字符是否在起始和结束标记之间。甚至不需要预览,只需解析文本并查看是否有剩余的标记。如果有,就会提示“此电子邮件包含非法标记”。 - Ňɏssa Pøngjǣrdenlarp
由于文本框是一个古老而疲惫的存在,而且它只包含文本,我怀疑除了事后检查之外,是否能有比此更好的解决方案。可以使用定时编辑,即在每次编辑期间重新启动的计时器,并在可能的2秒后达到其Tick时进行检查,并告知用户任何无效项;它甚至可以提供修复选项。 - TaW
显示剩余10条评论
1个回答

0

使用RichTextBox,您可以实现您想要的效果。

基本上下面的代码会查找前缀和后缀之间的字符串,在变量集合中搜索该字符串,如果找到该字符串,则整个标记字符串将被选中。

最终结果是,每当用户选择标记的一部分时,它将自动选择前缀和后缀之间的所有文本。

public partial class Form1 : Form
{
    public const char Prefix = '<';
    public const char Suffix = '>';
    private readonly List<string> _tags = new List<string> {"email"};

    public Form1() { InitializeComponent(); }

    private void richTextBox1_SelectionChanged(object sender, EventArgs e)
    {
        int startOfVar = 0;
        int endOfVar = -1;

        for (int i = richTextBox1.SelectionStart - 1; i >= 0; i--)
        {
            if (richTextBox1.Text[i] == Suffix)
                return;
            if (richTextBox1.Text[i] == Prefix)
            {
                startOfVar = i + 1;
                break;
            }
        }

        for (int i = startOfVar; i < richTextBox1.TextLength; i++)
        {
            if (richTextBox1.Text[i] == Suffix)
            {
                endOfVar = i;
                break;
            }
        }

        if (startOfVar < endOfVar)
        {
            var varString = richTextBox1.Text.Substring(startOfVar, endOfVar - startOfVar);

            if (_tags.Contains(varString))
            {
                richTextBox1.Select(startOfVar - 1, endOfVar - startOfVar + 2);
            }
        }
    }    

    private void button1_Click(object sender, EventArgs e)
    {
        richTextBox1.AppendText(Prefix + _tags[0] + Suffix);
    }
}

enter image description here


我马上检查一下 :) 那删除呢?当我把光标放在标签后面,然后按退格键或者放在前面按删除键时呢? - Misiu
当前的代码不会删除它。但是您可以更改它的行为方式。代码可能还存在其他一些缺陷,但这并不难克服。 - Sergey Rotbart

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接