【问题标题】:Adding a group of controls to a list将一组控件添加到列表
【发布时间】:2013-02-14 19:36:10
【问题描述】:

我正在尝试将 3 个 TextBox 控件的值添加到列表中,问题是这些控件是通过单击按钮以编程方式添加的。我不知道如何将 3 个文本框组合在一起,以便将它们的值添加到列表中。

这里有一些代码:

按钮点击添加控件:

protected void Button_Add_Click(object sender, EventArgs e)
{
    int count = 0;
    if (ViewState["count"] != null)
    {
        count = (int)ViewState["count"];
    }
    count = PlaceHolder_ForEntries.Controls.Count + 1;
    ViewState["count"] = count;
    createcontrols();
}

添加控件的方法

protected void createcontrols()
{
    int count = 0;
    if (ViewState["count"] != null)
    {
        count = (int)ViewState["count"];
    }
    while (PlaceHolder_ForEntries.Controls.Count < count)
    {
        TextBox TextBox_Name = new TextBox();
        TextBox TextBox_MemberNo = new TextBox();
        TextBox TextBox_Points = new TextBox();
        TextBox_Name.Attributes.Add("placeholder", "Navn");
        TextBox_Name.ID = "TextBox_Name" + PlaceHolder_ForEntries.Controls.Count.ToString();
        TextBox_Name.CssClass = "input-small";
        TextBox_MemberNo.Attributes.Add("placeholder", "Medlemsnr.");
        TextBox_MemberNo.ID = "TextBox_MemberNo" + PlaceHolder_ForEntries.Controls.Count.ToString();
        TextBox_MemberNo.CssClass = "input-small";
        TextBox_Points.Attributes.Add("placeholder", "Point");
        TextBox_Points.ID = "TextBox_Points" + PlaceHolder_ForEntries.Controls.Count.ToString();
        TextBox_Points.CssClass = "input-small";
        PlaceHolder_ForEntries.Controls.Add(TextBox_Name);
        PlaceHolder_ForEntries.Controls.Add(TextBox_MemberNo);
        PlaceHolder_ForEntries.Controls.Add(TextBox_Points);
        PlaceHolder_ForEntries.Controls.Add(new LiteralControl("<br />"));
    }
}

最后运行的代码点击保存按钮,将项目添加到列表中:

public struct content
{
    public string name;
    public string memberNo;
    public int points;
}

List<content> rows = new List<content>();

protected void LinkButton_Submit_Attendees_Click(object sender, EventArgs e)
{
    foreach (Control item in PlaceHolder_ForEntries.Controls)
    {
        if (item is TextBox)
        {
            string txt = item.ID.ToString(); // String to run RegEx on
            string re1 = ".*?"; // Non-greedy match on filler
            string re2 = "(\\d+)";  // Integer Number 1

            Regex r = new Regex(re1 + re2, RegexOptions.IgnoreCase | RegexOptions.Singleline);
            Match m = r.Match(txt);

            int id = Convert.ToInt32(m.Groups[1].ToString());
            TextBox txtBox = (TextBox)item;

            content row = new content();
            if(item.ID.Contains(id.ToString()) && item.ID.Contains("Name"))
            {
                row.name = txtBox.Text;
            }
            else if (item.ID.Contains(id.ToString()) && item.ID.Contains("MemberNo"))
            {
                row.memberNo = txtBox.Text;
            }
            else if (item.ID.Contains(id.ToString()) && item.ID.Contains("Points"))
            {
                row.points = Convert.ToInt32(txtBox.Text);
            }
            rows.Add(row);
        }
    }
}

我需要的是,对于该迭代的每三个控件,rows.Add(row) 被调用,row.name, row.memberNo and row.points 都具有它们各自的值。

【问题讨论】:

  • 如果我了解您的基本要求,我会使用 TableLayoutPanel 来做到这一点。
  • 添加一个从 1 开始的 int 计数器,并检查 if (counter % 3 == 0) 是否可以被 3 整除。

标签: c# iteration


【解决方案1】:
  1. 你可以使用Linq的OfTypePlaceHolder中找到你所有的TextBoxes

    var alltxt = PlaceHolder_ForEntries.Controls.OfType<TextBox>();
    

您可以为所有人使用 Linq:

List<content> rows = PlaceHolder_ForEntries.Controls.OfType<TextBox>()
    .Select(txt => new{
        Txt = txt,
        Number = new String(txt.ID.SkipWhile(c => !Char.IsDigit(c)).ToArray())
     })
    .GroupBy(x => x.Number)
    .Select(g => new content{ 
        name = g.First(x => x.Txt.ID.StartsWith("TextBox_Name")).Txt.Text,
        memberNo = g.First(x => x.Txt.ID.StartsWith("TextBox_MemberNo")).Txt.Text,
        points = int.Parse(g.First(x => x.Txt.ID.StartsWith("TextBox_Points")).Txt.Text)
    })
    .ToList();

我按您用于 ID (1-n) 的数字后缀进行分组。

【讨论】:

  • 这看起来是一个非常聪明的解决方案,虽然我没有使用 Linq 的经验。不过,我对您的解决方案确实有一些疑问:在这一行 Number = new String(txt.Id.SkipWhile(c =&gt; !Char.IsDigit(c))) Visual Web Developer 2010 Express 抛出此异常:` 'System.Web.UI.WebControls.TextBox' 不包含 'Id' 的定义并且没有扩展方法可以找到接受“System.Web.UI.WebControls.TextBox”类型的第一个参数的“Id”(您是否缺少 using 指令或程序集引用?)`如果我将 Id 更改为 ID 它会告诉我重载的方法有 inv。参数
  • 抱歉,评论中的字符已用完。
  • @KasperMackenhauerJacobsen:当然,webcontrols 中的属性是ID 而不是Idstring 构造函数采用Char[] 而不是IEnumerable&lt;Char&gt;,所以调用ToArray()在最后。编辑了我的答案。 :)
  • 更新了我的答案,请注意我也将...Text 更改为....Txt.Text,因为group.First 返回一个匿名类型的实例,其中包含一个引用Txt 的属性TextBox .
  • 哦,哇,我同意了你的回答,因为你刚刚让我看到了 Linq,我真的要研究一下 Linq!看起来像一个真正的节省时间,无论是在性能方面还是在编码方面。
【解决方案2】:

我会更改您的 LinkBut​​ton_Submit_Attendees_Click 功能:

protected void LinkButton_Submit_Attendees_Click(object sender, EventArgs e)
{
        content row = new content();
foreach (Control item in PlaceHolder_ForEntries.Controls)
{
    if (item is TextBox)
    {
        string txt = item.ID.ToString(); // String to run RegEx on
        string re1 = ".*?"; // Non-greedy match on filler
        string re2 = "(\\d+)";  // Integer Number 1

        Regex r = new Regex(re1 + re2, RegexOptions.IgnoreCase | RegexOptions.Singleline);
        Match m = r.Match(txt);

        int id = Convert.ToInt32(m.Groups[1].ToString());
        TextBox txtBox = (TextBox)item;

        if(item.ID.Contains(id.ToString()) && item.ID.Contains("Name"))
        {
            row.name = txtBox.Text;
        }
        else if (item.ID.Contains(id.ToString()) && item.ID.Contains("MemberNo"))
        {
            row.memberNo = txtBox.Text;
        }
        else if (item.ID.Contains(id.ToString()) && item.ID.Contains("Points"))
        {
            row.points = Convert.ToInt32(txtBox.Text);
        }
if(!string.IsNullOrEmpty(row.name)
  && !string.IsNullOrEmpty(row.memberNo)
  && row.points > 0)){
        rows.Add(row);
        row = new content();
}
    }
}

}

【讨论】:

  • 部分有效!剩下的唯一问题是row.pointsint,因此每次都验证为真。我尝试了!string.IsNullOrEmpty(row.points.ToString))row.points.ToString() != "" 仍然验证为真,它只是在row.points 中添加了一个“0”。虽然这个 可以 为“0”,但它不是我提供的 TextBox 的值。这个问题有什么解决办法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-31
  • 1970-01-01
  • 1970-01-01
  • 2018-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多