如何使用TextBox动态替换部分文本?

时间:2011-05-16 21:34:51

标签: c# asp.net textbox dynamic-controls

TL; DR:

我需要在PlaceHolder中插入一个TextBox,无论我在哪里看到@token@这样的标记,并且@上的分割都不会删除它。我怎么能这样做?

设置:

我有一个数据库驱动的ASP.NET页面,其中包含多个地方的合并字段。在其中一个管理页面上,我想通过显示合并字段所在的TextBox来使合并字段中的文本可编辑。文本的其余部分需要保持不可编辑状态。

输入如下:

  

“快速的棕色狐狸 @foo @ 跳过 @bar @ 懒惰的 @baz @ 狗。”

此处的合并字段为foobarbaz。我有一个Dictionary<string, string>,其中包含合并字段的值:

var Tokens = new Dictionary<string, string>
{
    { "foo", "john" },
    { "bar", "george" },
    //...etc...
};

目标:

对于每个文本块,我都有一个PlaceHolder。我想要做的是为每个不可编辑文本块动态插入一个Label,为每个可编辑块动态插入一个TextBox。所以上面的结果就好像我有这样的硬编码:

<asp:Label   Text="the quick brown fox" />
<asp:TextBox ID="foo" Text="john" />
<asp:Label   Text="jumps over" />
<asp:TextBox ID="bar" Text="george" />
<asp:Label   Text="the lazy" />
...etc...

问题:

匹配@token@模式很简单。诀窍是在正确的位置添加标签和文本框。在给定输入中可能有多个令牌,因此我必须将其分离为可编辑和不可编辑的文本,同时仍然跟踪每个TextBox对应的合并变量。当它转动时出来,这并不像听起来那么容易。我可以使用正则表达式将输入字符串转换为HTML,将@token@模式替换为<input>标记。但是,这有几个问题:

  • 我已经有了大量的动态服务器控制方法代码。
  • 我只想匹配特定的令牌,因此/@[a-zA-Z\d]+@/不够严格。

以前的策略:

到目前为止,我只是将输入字符串拆分为@,然后为每个奇数子字符串插入一个Label,为每个偶数子字符串插入一个TextBox。这很好,但要求正在改变。现在,@符号将被允许在变量名之外,因此输入字符串可能如下所示:

  

blah blah@blah.com @foo @ blah

...在这种情况下,只有foo是合并字段。

当前战略:

我觉得我需要遍历Tokens并构建某种Labels和TextBoxes数组。问题是输入中可能存在任意数量的令牌,因此一旦我为@foo@分割出TextBox,我需要再次查看文本 以查找@bar@的实例。我想我需要某种递归,但我不能完全指责它。

2 个答案:

答案 0 :(得分:2)

你可以用正则表达式来做。 表达式看起来像:

@([a-zA-Z0-9])+@

这意味着它匹配所有以@开头的模式,包含至少一个字符a-z或A-Z或0-9并以@

结尾

Regex.Match

答案 1 :(得分:0)

fantasticfix 的回答发布之前,我开始使用字符串操作处理递归方法。它似乎工作正常,所以我在这里张贴给其他人:

private void tokenize(PlaceHolder ph, string str)
{
    int index = str.IndexOf('@') + 1;

    if (index == 0)
    {
        ph.Controls.Add(new Label { Text = str });
        return;
    }

    ph.Controls.Add(new Label { Text = str.Substring(0, index - 1) });

    if (Tokens.Keys.Any(k => str.Substring(index).StartsWith(k + "@")))
    {
        int next = str.IndexOf("@", index);
        string key = str.Substring(index, next - index);

        ph.Controls.Add(new TextBox
        {
            ID = "txt" + key,
            Text = Tokens[key],
            TextMode = TextBoxMode.MultiLine,
            Rows = 2
        });

        index = next + 1;
    }

    tokenize(ph, str.Substring(index));
}