在 Repeater 控件的页脚中查找控件返回文本框为空值。

5

我有两个嵌套的重复器。在嵌套的重复器的页脚中,我有文本框和文件上传控件。我能够轻松获取文件上传的实例,但是文本框的实例为空,尽管它们都放置在页脚中。

下面是表示内部重复器页脚的aspx部分:

<FooterTemplate>
            <tr class="add_comment">
                <td>Add comment </td>

            </tr>
            <tr>
                <td>
                    <asp:TextBox runat="server" Columns="20" Rows="3" ID="comment_txt" TextMode="MultiLine" Width="60%" CssClass="new_comment" ViewStateMode="Inherit"></asp:TextBox>

                </td>

             </tr>

           <tr class="add_comment">
                <td>
                            <asp:FileUpload ID="uploadImageBtn" runat="server" Text="Add image" OnClick="uploadImage" CssClass="comment_buttons" />

                            <asp:Button ID="comment_btn" runat="server" OnClick="submitComment" Text="Comment" CssClass="comment_buttons" />
                </td>
       </tr>

         </table>
     </FooterTemplate>

这是我试图访问控件的C#代码:
protected void commentsRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if ((e.Item.ItemType == ListItemType.Footer ))
            {
                Repeater childRepeater = (Repeater)sender;
                TextBox commentTextBox = (TextBox)e.Item.FindControl("comment_txt");
                String postText = commentTextBox.Text.ToString(); 
                FileUpload upFile = (FileUpload)e.Item.FindControl("uploadImageBtn");
            }
        }

当运行页面时,我遇到了这个错误:
Object reference not set to an instance of an object 

由于这行代码的存在导致了这个问题:
String postText = commentTextBox.Text.ToString(); 

我尝试删除文本框代码,只检索上传文件,结果非常好。问题在于访问文本框。

编辑:应该在同一页的按钮的onclick事件处理程序中访问文本框的访问文本和上传按钮的实例。因此,我定义了两个全局变量,在执行Repeater的某些嵌套重复器事件(例如ItemDataBound或由Adrian Iftode建议的事件ItemCreated)时分配它们的值。然后,在按钮的onclick中使用它们,假设它们具有值,因为嵌套的repeater事件应在按钮的 onclick之前触发。成功检索上传文件实例,但始终为空的文本框。

全局变量声明:

  TextBox commentTextBox;
    FileUpload upFile;
    Repeater childRepeater;
    String postText; 

嵌套重复器事件内的代码:

 protected void commentsRepeater_ItemCreated(object sender, RepeaterItemEventArgs e)
        {
            if ((e.Item.ItemType == ListItemType.Footer))
            {
                 childRepeater = (Repeater)sender;
                 commentTextBox = (TextBox)(e.Item.FindControl("comment_txt"));
                 postText = commentTextBox.Text.ToString();
                upFile = (FileUpload)e.Item.FindControl("uploadImageBtn");
            }
        }

点击事件内的代码:

protected void submitComment(object sender, EventArgs e)
        {


            Boolean insert = true;
            if (upFile.HasFile || !String.IsNullOrEmpty(postText))
            {
                   //some code. 
              }

上述if语句仅在upFile有文件时执行,postText始终被视为null。

请问有谁能帮我解决这个错误吗?

谢谢。


转换是原因。 (TextBox)(e.Item.FindControl("comment_txt")); 有帮助吗? - Sami
@Sami 谢谢你的回复,但是我还不是很明白你的意思。我使用这个转换来获取文本框的实例,然后检索它的文字内容。能否请您更详细地解释一下为什么这个转换会导致问题,以及如何解决呢?非常感谢。 - Dania
只是猜测,由于您得到了一个空引用,很可能是转换失败,因此返回了null。在您的原始代码中(我怀疑),编译器正在尝试将“e”转换为文本框,这是不可能的。我添加了括号,以便e.Item.FindControl的结果是编译器应该尝试转换的内容。 - Sami
@Sami,谢谢你的建议,我尝试了,但仍然出现相同的错误。请告诉我是否有其他可能的解决方案。 - Dania
1个回答

2

在这种情况下,ItemDataBound不是处理的正确事件,因为重复项中未实例化标题和页脚模板。

正确的事件是ItemCreated。

protected void rp_ItemCreated(Object sender, RepeaterItemEventArgs e)
{
            if (e.Item.ItemType == ListItemType.Footer)
            {    
              e.Item.FindControl(ctrl);
            }
            if (e.Item.ItemType == ListItemType.Header)
            {
              e.Item.FindControl(ctrl);
            }
}

谢谢,我尝试了这个方法,它只在本地范围内有效。当我将字符串postText定义为全局变量,并从ItemCreated中检索其值时,全局字符串的值保持为空。我在一个按钮的onclick方法中检查字符串的值。您能告诉我为什么会发生这种情况吗?非常感谢。 - Dania
postText是什么? - Adrian Iftode
@ Adrian Iftode,这是一个字符串,用于存储输入文本框中输入的文本值。我想在单击“comment_btn”按钮时获取文本框中的文本。由于文本框位于嵌套重复器内部,除非在其中一个嵌套重复器事件(如ItemCreated)中获取它的实例,否则我将无法获取它的实例,同时此文本应该可以从onclick内部访问。因此,我全局定义了postText,并在重复器事件中将其赋值为文本的值。我认为重复器事件必须在onclick之前执行。你能帮我吗?是什么导致了这个错误?谢谢。 - Dania
我认为对你来说更好的做法是构建一个非常简单的示例,其中包括嵌套的重复器,这样我可以更好地查看。也许有一种更简单的方法来实现你想要的功能。 - Adrian Iftode
非常感谢,我已经更新了问题,请检查并告诉我如何解决这个问题。非常感谢。 - Dania

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接