【问题标题】:FindControl returns nullFindControl 返回 null
【发布时间】:2012-12-21 18:10:33
【问题描述】:

我正在研究 C# 和 ASP.NET 4.0 中的解决方案我试图从我的页面中获取单选按钮的值,该页面是基于一些数据库信息动态创建的。

以下是页面源中生成的内容:

<td>
  <input id="masterMain_3Answer_0" type="radio" name="ctl00$masterMain$3Answer"     
    value="Y" onclick="return answeredyes(3);" />
  <label for="masterMain_3Answer_0">Y</label>
</td>
<td>
  <input id="masterMain_3Answer_1" type="radio" name="ctl00$masterMain$3Answer" 
    value="N" onclick="return answeredno(3,&#39;desc&#39;);" />
  <label for="masterMain_3Answer_1">N</label>
</td>

在我的提交按钮的 OnClick 函数中,我想根据用户的输入收集是否选择了 Y 或 N。

这是我目前所写的:

      RadioButton _rbAnswer = new RadioButton();
      RadioButtonList _rbList = new RadioButtonList();


     ContentPlaceHolder cp = (ContentPlaceHolder)Master.FindControl("masterMain");
     _rbAnswer = (RadioButton)Master.FindControl("masterMain_3Answer_0");
     HtmlInputRadioButton rb = (HtmlInputRadioButton)Master.FindControl("masterMain_3Answer_0");


     _rbAnswer = (RadioButton)cp.FindControl("masterMain_3Answer_0");
     _rbList = (RadioButtonList)cp.FindControl("masterMain_3Answer_0");

我能够毫无问题地获取 ContentPlaceHolder,但其余对象在尝试获取 .我也尝试删除“masterMain_”,但仍然不想找到控件。

这是添加单个单选按钮列表的代码

                TableRow _tempRow = new TableRow();
                TableCell _cellOK = new TableCell();


                 RadioButtonList _rbList = new RadioButtonList();
                _rbList.ID = r[0].ToString()+"Answer";
                _rbList.RepeatDirection = RepeatDirection.Horizontal;

                //add options for yes or no
                 ListItem _liOk = new ListItem();
                _liOk.Value = "Y";
                 ListItem _linotOk = new ListItem();
                _linotOk.Value = "N";
                _rbList.Items.Add(_linotOk);

                //add cell to row
                _rbList.Items.Add(_liOk);
                _cellOK.Controls.Add(_rbList);
                _tempRow.Cells.Add(_cellOK);

                 //add the row to the table
                 stdtable.Rows.Add(_tempRow);

【问题讨论】:

  • rbList.SelectedValue 有什么问题?
  • 这是我想做的,但 rbList 为空,因为我没有正确获得控制
  • 如果您首先发布涉及添加控件的代码,我们都会受益。您试图找到控件的部分毫无意义,因为我们没有真正的参考框架。

标签: c# asp.net master-pages contentplaceholder


【解决方案1】:

为了能够快速找到动态创建的控件,请将字典添加到您的页面类中:

private Dictionary<string, Control> fDynamicControls = new Dictionary<string, Control>();

然后在代码中创建新控件并分配其 ID 时:

fDynamicControls.Add(newControl.ID, newControl);

当您需要控件的参考时:

Control c = fDynamicControls["controlIdThatYouKnow"];

【讨论】:

    【解决方案2】:

    使用 FindControl 时不要使用页面生成的 id。使用您在 aspx 中指定的 ID。

    如果这是在一个Repeater或另一个DataBound控件内,你必须首先找到当前记录。 (GridViewRow 或 RepeaterItem)首先,使用该项目的 .FindControl 函数。

    请参阅此(不同 - 不重复)问题以查看如何执行此操作的代码示例:How to find control with in repeater on button click event and repeater is placed with in gridview in asp.net C#

    【讨论】:

    • 谢谢。我实际上并没有在 ASPX 页面内创建对象。在创建页面时,我通过我的 C# 代码动态创建它。 'TableCell _cellOK = new TableCell(); RadioButtonList _rbList = new RadioButtonList(); _rbList.ID = r[0].ToString()+"答案"; _rbList.RepeatDirection = 重复方向。水平; ListItem _liOk = new ListItem(); _liOk.Value = "Y"; _rbList.Items.Add(_liOk);'
    • 我还能如何获取这些数据?
    【解决方案3】:

    当您创建动态控制器时,请为它们指定特定的 ID。这有助于使用我们自己的 id 生成控件。因此我们可以使用这个 id 访问控件。

    并且还使用 OnInit 生命周期事件来生成动态控制器,这里是生成它们的最佳位置。

     RadioButton _rbAnswer = new RadioButton();
     _rbAnswer.ID="ranswerid";
    

    【讨论】:

      【解决方案4】:

      根据您的更新,您会发现您的控制层级相当深。您在表格内的一行内的单元格内有一个 RadioButtonList ...

      FindControl 是一种需要在特定对象上调用的方法,并且只能找到该对象的实际子对象。在这种情况下,您要么需要构建递归方法,要么直接转到相关控件。由于这些控件中有很多是动态生成的,因此您无法直接访问它们,因此构建递归函数可能是最简单的。但是,在非常大的页面上,这种方法可能会非常消耗资源:

      public static WebUserControl FindControlRecursive(this WebUserControl source, string name) 
      {
          if (source.ID.Equals(name, StringComparison.Ordinal))
              return source;
      
          if (!source.Controls.Any()) return null;
      
          if (source.Controls.Any(x => x.ID.Equals(name, StringComparison.Ordinal))
              return source.FindControl(name);
      
          WebUserControl result = null;
      
          // If it falls through to this point then it 
          // didn't find it at the current level
          foreach(WebUserControl ctrl in source.Controls)
          {
              result = ctrl.FindControlRecursive(name);
              if (result != null) 
                  return result;
          }
      
          // If it falls through to this point it didn't find it
          return null;
      }
      

      这是一个扩展方法,允许您在 ContentPlaceHolder 控件上调用它:

      var _cp = (ContentPlaceHolder)Master.FindControl("masterMain");
      RadioButtonList _rbList = _cp.FindControlRecursive("3Answer");
      
      if (_rbList != null)
         // ... Found it
      

      注意:将以上内容视为伪代码。我还没有在任何地方实现它,所以可能(可能)需要调整才能完全正确。

      【讨论】:

        猜你喜欢
        • 2013-09-20
        • 2012-08-18
        • 1970-01-01
        • 1970-01-01
        • 2019-01-09
        • 2012-11-21
        • 2012-10-31
        • 2013-03-16
        • 2010-10-05
        相关资源
        最近更新 更多