【问题标题】:c# equivalent to document.getElementById("ListBox"+i+"Item"+j).selected=truec#等价于document.getElementById("ListBox"+i+"Item"+j).selected=true
【发布时间】:2019-02-14 17:08:20
【问题描述】:

我使用严格的 html、javascript 和 MS Access 创建了一个动态网页。虽然它是功能性的,但在本地部署它存在复杂性。由于我已将数据移植到 MySQL 并尝试使用 Visual Studio 的 aspx.cs 来完成 javascript 之前所做的大部分工作。

我有一个屏幕,它根据查询结果填充一组动态行(每条记录两行以美观),其中一个单元格包含一个下拉菜单(html select/asp:ListBox)。

当我只在 javascript 上拥有一切时,我可以创建单元格,然后创建其内容,然后使用以下方法设置所选值:

 document.getElementById("StatusDD" + rowCount).value = reader.GetValue(i);

根据我目前收集到的信息,大致相当于:

 ListItem li = StatusDD1.Items.FindByValue(reader.GetValue(i));
 li.Selected = true;

但是,我不能简单地对 StatusDD1 到 StatusDDx 进行硬编码(例如,一开始我的硬编码集可能大于返回的记录数,而最终返回的两个行将大于硬编码值的集)。

所以我所做的是我创建了以下函数:

 protected void setSelected(string selectId, string value)
     {
         /*Need to put something here to make the following work*/
         selectId.Items.FindByValue(value).Selected = true;
     }

传入的 selectId 是 ListBox 的名称/id,值是从查询返回的值。 它被称为:

 setSelected("StatusDD" + rowCount, (string)reader.GetValue(i));

如果我可以实现由“StatusDD”+rowCount 创建的名称,因为没有更好的短语,我可以像传入 ListBox 而不是字符串一样传入该名称。

或者,如果有办法从数组中选择 ListBox,我可以在其中进行条件检查 WHERE/IF ListBox.Name = selectId,类似于以下 PseudoCode

 ListBox a = ListBox.NameMatches(selectId);
 a.Items.FindByValue(value).Selected = true;

目前通过在字符串中定义框然后将该字符串传递给 HtmlTableCell 来创建 ListBox:

     HtmlTable myTable = new HtmlTable();
     HtmlTableRow newRow;
     string cellId;
     string cellContents;
     int rowCount = 1;
     string statusDisabled = "";

     while (reader.Read()){
        newRow = new HtmlTableRow();
        myTable.Rows.Add( newRow );
        ...
        ...
        cellContents = "<asp:ListBox name='StatusDD" + rowCount + "' id='StatusDD" + rowCount + "' style='width:100%; " + statusDisabled + "' value='" + reader.GetValue(i) + "' onchange='markNeedSave(" + (rowCount + 1) + ")'><asp:ListItem value='0'></asp:ListItem><asp:ListItem value='1'>New</asp:ListItem>....asp:ListBox>";

        newRow.Cells.Add(new HtmlTableCell{InnerHtml = cellContents});
     }

如果有帮助,这就是我在 javascript 中的工作方式:

     while (!rs.EOF) {
        rowa = table.insertRow(rowCount);
        rowa.id = "RECORD" + rowCount + "a";
        cell = rowa.insertCell(i + 1);
        cell.id = "RECORD" + rowCount + "_CELL" + (i + 1);

        for (i = 0; i < 8; i++) {
           cell.innerHTML = "<select name='StatusDD" + rowCount + "' id='StatusDD" + rowCount + "' style='width:100%' value='" + rs.fields(i).value + "' onchange='markNeedSave(" + (rowCount + 1) + ")'><option value='NONE'></option><option value='New'>New</option>...</select>";
           if (readonly) {
               document.getElementById("StatusDD" + rowCount).disabled = true;
           }
           document.getElementById("StatusDD" + rowCount).value = rs.fields(i).value;
        }
     ...
     }

好的,让 ListBox 工作,但是当我研究时,当我终于让它工作时,我发现我想要的是 DropDownList,而不是 ListBox,但同样的修复需要完成才能让其中任何一个工作。

我现在使用以下函数:

    protected void setSelected(string selectId, string value)
    {
       PlaceHolder TCS = Page.FindControl("TestingCS") as PlaceHolder;
       DropDownList ddl = TCS.FindControl(selectId) as DropDownList;
           if (ddl != null)
           {
                ddl.SelectedValue = value;
                ListItem item = ddl.Items.FindByValue(value);
                if(item != null)
                {    item.Selected = true;}
           }
    }

另外,对于只包含数据的单元格内容,使用以下内容很好:

    cellContents = "<someString>";
    newRow.Cells.Add(new HtmlTableCell{InnerHtml = cellContents});

但是对于我的下拉列表(或列表框),我需要使用:

    cell = new HtmlTableCell();
    newRow.Cells.Add(cell);
    DropList = new DropDownList();
    DropList.ID = "StatusDD" + rowCount;
    DropList.Items.Add(new ListItem("", "0"));
    DropList.Items.Add(new ListItem("New", "1"));
    ...

    cell.Controls.Add(DropList);
    setSelected(DropList.ID, (string)(reader.GetValue(i)));

更流畅的解决方案:

    protected void setSelected(DropDownList ddl, string value)
    {
        ListItem item = ddl.Items.FindByValue(value);
        if (item != null)
        { item.Selected = true; }
    }

...

    protected void accessRecord()
    {
        ...
        DropList = new DropDownList();
        DropList.ID = "StatusDD" + rowCount;
        DropList.Attributes["onChange"] = "javascript:markNeedSave(" + rowCount + ");";
        DropList.Items.Add(new ListItem("", "0"));
        DropList.Items.Add(new ListItem("New", "1"));
        ...
        cell.Controls.Add(DropList);
        setSelected(DropList,(string)reader.GetValue(i));
    }
    ...

【问题讨论】:

  • 您是如何创建列表框的?这是 WebForms 吗?
  • 对于您的第一个问题,我已将其添加到上述问题的末尾。对于第二个,是的:ASP.NET Web 窗体站点。
  • 你测试过这种方法的输出吗?将服务器控件添加为字符串不会像您期望的那样呈现它们。我建议改为实例化然后填充一个 ListBox 并将其添加到 HtmlTableCell 的 Controls 属性以及 Dictionary&lt;string,ListBox&gt; 字段,然后您可以通过您提供的任何 ID 作为键检索该列表框。跨度>
  • 类似:Dictionary&lt;string,ListBox&gt; ListBoxList = new Dictionary&lt;string,ListBox&gt;(); ... ListBoxList.Add("StatusDD" + rowCount,new ListBox()); ?

标签: c# html asp.net webforms


【解决方案1】:

听起来您要查找的函数是FindControl。这可以从 Page 或您可能创建的用于保存输出的任何父控件中使用。

setSelected 方法的示例实现可能如下所示:

 protected void SetSelected(string selectId, string value)
 {
     var lb = Page.FindControl(selectId) as ListBox;
     if (lb != null)
     {
         var item = lb.Items.FindByValue(value)
         if(item != null)
             item.Selected = true;
     }
 }

【讨论】:

  • 到目前为止,这个概念似乎有效,但是我遇到了一些我认为与人口顺序有关的问题。 lb 对于每次迭代都是空的,我认为这是因为表及其内容尚未写入页面以供控件查找它们。但是,如果我在创建行之前填充表,则表会被创建并填充,但不会填充行,因此会出现相同的 null 问题。一旦我解决了这个问题,我相信我将能够确认这是我需要的答案。
  • 您确定为您创建的每个列表框设置 ID 属性吗?
  • 检查元素时的结果如下:&lt;asp:ListBox name="StatusDD1" id="StatusDD1" style="width:100%; disabled=''" value=2 onchange="markNeedSave(2)" SelectionMode="Single"&gt;&lt;asp:ListItem value=0&gt;&lt;/asp:ListItem&gt;&lt;asp:ListItem value=1&gt;New&lt;/asp:ListItem&gt; 在调试期间 lb 仍然返回 null。
  • @wolfsshield 您是否在运行 SetSelected 之前将控件添加到页面?您是否仍在尝试将列表框添加为 InnerHtml 或者您是否已开始创建控件并添加它们?
  • 要试试这个:stackoverflow.com/a/9830488/11035837 两者都有一点,仍在过渡到创建控件
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-08
  • 1970-01-01
  • 1970-01-01
  • 2015-08-26
  • 2017-01-13
  • 2015-02-10
相关资源
最近更新 更多