【问题标题】:How can I dynamically replace portions of text with TextBoxes?如何用 TextBoxes 动态替换部分文本?
【发布时间】:2011-05-16 21:34:50
【问题描述】:

TL;DR:

我需要将 TextBox 插入到 PlaceHolder 中,只要我看到像 @token@ 这样的标记,并且在 @ 上拆分不会削减它。我该怎么做?

设置:

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

输入看起来像这样:

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

此处的合并字段为foobarbaz。我有一个带有合并字段值的Dictionary<string, string>

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

目标:

对于这些文本块中的每一个,我都有一个 PlaceHolder。我想做的是为每个不可编辑的文本块动态插入一个标签,为每个可编辑的块动态插入一个 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@ 模式替换为 &lt;input&gt; 标记。但是,这有几个问题:

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

以前的策略:

到目前为止,我只是将输入字符串拆分为@,然后为每个奇数子字符串插入一个标签,为每个偶数子字符串插入一个文本框。效果很好,但是要求正在发生变化。 @ 符号现在可以在变量名之外使用,因此输入字符串可能如下所示:

blah blah@blah.com @foo@ blah

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

当前策略:

我觉得我需要遍历令牌并构建某种标签和文本框数组。问题是输入中可能包含任意数量的标记,所以一旦我为@foo@ 拆分出TextBoxes,我需要再次查看@bar@ 的实例。我想我需要对此进行某种递归,但我不能完全确定它。

【问题讨论】:

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


    【解决方案1】:

    您可以使用正则表达式来做到这一点。 表达式看起来像:

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

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

    Regex.Match

    【讨论】:

    • +1,你也可以检查匹配的名字是否真的作为一个变量存在,如果不把它当作普通文本对待。
    • 问题与模式不匹配。这不是太难。问题是动态添加标签和文本框,并找出标签/文本框放在哪里。
    • 然后你使用链接中的代码 sn-p 循环匹配,并将找到的匹配替换为文本。 match 的返回值是“System.Text.RegularExpressions.Match”,其中包含 Index(从哪里开始)Lenght(匹配的长度)和 value(找到的子字符串)。有了这些值,替换它应该是小菜一碟。
    • 您之前的问题是无法识别单个@。 (至少那是您所说的问题)使用正则表达式解决方案您解决了这个问题
    • 这还不是问题的全部;这更像是一个小改动,搞砸了之前的解决方案。不过,我正在考虑这个想法……我也许可以让它发挥作用。但是,它无法处理像blah blah@blah@foo@ blah 这样的输入,其中@foo@ 是唯一的变量。
    【解决方案2】:

    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));
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-09
      • 2019-11-10
      • 1970-01-01
      • 2012-10-18
      • 2020-04-12
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      相关资源
      最近更新 更多