主细节空参考例外

时间:2012-01-24 20:34:31

标签: c# asp.net

让我们深入了解为什么我会收到此错误,实际上更好,如何修复它。我在gridview中有一个嵌套的gridview。可能有更好的方法但是在这一点上我已经有了模态弹出工作,这也是永远的,所以除非这是显示主 - 细节的完全愚蠢的方式然后现在这样说。

我能够将datakey id传递给详细信息网格,但这就是我得到空引用异常的地方,我猜这个bugger还没有存在,或者是不可见的。我的意思是,无论什么原因,我该如何解决这个问题?谢谢你的推荐。

aspx文件:

<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
    <asp:GridView ID="gvForum" runat="server" DataSourceID="odsForumApproval" DataKeyNames="id" Width="200px" 
      RepeatColumns="1" DataKeyField="id"  CssClass="gridview"
      AutoGenerateColumns="False" GridLines="None"  OnSelectedIndexChanged="_OnCommand">
      <AlternatingRowStyle CssClass="altbgcolor"  />
      <Columns>   
      <asp:TemplateField >
      <ItemTemplate>
      <asp:Label runat="server" ID="lblTitle" Text='<%# Bind("Title") %>' />                                

      <asp:Panel id="div" runat="server" align="center" class="confirm" style="display:none"  >
      <asp:GridView runat="server" ID="gvForumDetail" AutoGenerateColumns="False" DataKeyNames="id"
      EmptyDataText="No Forum Detail"  AllowPaging='true'
      AllowSorting="true" PageSize="5"  >
      <AlternatingRowStyle CssClass="altbgcolor" />
      <RowStyle VerticalAlign="Top" HorizontalAlign="Left" />
      <Columns>
        <asp:TemplateField>
          <ItemTemplate>
            <asp:Label runat="server" ID="lblTraining" Text='<%# Bind("title") %>' />
          </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField>
          <ItemTemplate>
            <asp:Label runat="server" ID="lblCompletionDate" Text='<%# Bind("description") %>' />
          </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField>
          <ItemTemplate>
            <asp:Label runat="server" ID="lblRecurence" Text='<%# Bind("MemberName") %>' />
          </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField>
          <ItemTemplate>
            <asp:Label runat="server" ID="lblNotes" Text='<%# Bind("itemdate") %>' Width="200" />
          </ItemTemplate>
        </asp:TemplateField>
        <asp:CommandField ShowCancelButton="true" ShowEditButton="true" ShowDeleteButton="true" />
      </Columns>
      </asp:GridView>                               
      <br />
      <asp:Button ID="btnClose" runat="server" Text="Close" Width="50px" />                               
      </asp:Panel>   

      <ajaxToolKit:ModalPopupExtender ID="ModalPopupExtender1" runat="server"                                        
      TargetControlID="lblTitle" 
      PopupControlID="div" 
      CancelControlID="btnClose"  
      BackgroundCssClass="modalBackground" />

      </ItemTemplate>
      </asp:TemplateField>
      <asp:CommandField ShowSelectButton="True" ShowDeleteButton="true" />
      </Columns> 
      </asp:GridView>

代码文件:

public void _OnCommand(object sender, EventArgs e)
{
    ObjectDataSource ods = new ObjectDataSource();
    ods.ID = "ods_ForumDetail";
    ods.EnableViewState = true;
    ods.TypeName = "Forum";
    ods.SelectMethod = "GetForumPostByID";

    string id = "";
    int rowIndex = gvForum.SelectedIndex;
    id = gvForum.DataKeys[rowIndex].Value.ToString();
    ods.SelectParameters.Add("id", System.TypeCode.Int32, id);

    GridView gvForumDetail = (GridView)Master.FindControl("ContentPlaceHolder1").FindControl("gvForum").FindControl("gvForumDetail");
    gvForumDetail.DataSource = ods;
    gvForumDetail.DataBind();
}

2 个答案:

答案 0 :(得分:2)

你还没有告诉你到底在哪里得到了null-reference-exception。 但是你为什么要通过MasterPage以间接方式找到你的Detail-Grid?

直接的方式更容易,最重要的是不容易出错:

var gvForum = (GridView)sender;
var gvForumDetail = (GridView)(gvForum.SelectedRow.FindControl("gvForumDetail"));

除此之外,您找到嵌套GridView的方法永远不会有效。 FindControl只会搜索当前NamingContainer的给定ID。因此,以下可能有效,但是将Master与其中一个ContentPages硬连接总是坏的:

(GridView)Master.FindControl("ContentPlaceHolder1").FindControl("gvForum");

但是这不会引导您进入嵌套的GridView,因为......

gvForum.FindControl("gvForumDetail");

...不会在GridView中搜索gvForumDetail的所有GridViewRows,而只搜索GridView本身的NamingContainer。 GridViewRow有它自己的NamingContainer(虽然存在多行,但是在ItemTemplate中使用相同的ID),所以唯一正确的方法是获取当前的SelectedRow并在那里搜索嵌套的Grid(见上文)。

您尚未显示嵌套GridView的DataBind位置。这应该在外部GridView的RowDataBound中完成。这可能是它为空的原因。 获取NullRefernceException的另一个原因可能是您可能在page_load中的每个回发中使用DataBinding外部GridView,而不仅仅是if(!IsPostBack)。这将取消选择你的​​网格,导致SelectedRow在我的方法中没有任何意义。

答案 1 :(得分:0)

以下是有关如何执行嵌套网格视图的简单演练。 Link

我同意蒂姆的意见,你正在做一些奇怪的事情。我还会声明性地在HTML中创建您的objectdatasource,这样您就不必动态地创建每个命令。

<强>更新 这是另一个Link这是一个视频,一步一步地向您展示如何做您想做的事情并将选择参数传递给您的内部gridview。 (约3:40)。