DetailsView FindControl () возвращает нуль после некоторых обратных передач - PullRequest
0 голосов
/ 07 января 2010

Я долгое время работал с GridViews и DetailsViews, но вчера я столкнулся с новым сценарием, который я совершенно не понимаю.

У меня есть GridView с ImageButton (CommandName = "Insert"), который изменит режим DetailsView для вставки. После этого я буду искать DropDownList внутри этого DetailsView и динамически добавлять некоторые элементы. Работает нормально, но первый раз, когда я нажимаю эту кнопку ImageButton. Если я нажимаю «Отмена» в DetailsView и снова нажимаю ImageButton, метод .FindControl () возвращает ноль. С какой проблемой жизненного цикла я сталкиваюсь здесь?

Я создал этот пример: (Чтобы он работал в вашей Visual Studio, просто свяжите источник данных с DetailsView, иначе он не будет отображен)

Markup:

<asp:GridView ID="gvCategory" runat="server" OnRowCommand="gvCategory_RowCommand">
    <Columns>
    </Columns>
    <EmptyDataTemplate>
        <asp:ImageButton ImageUrl="~/images/add.png" ID="ibAdd" runat="server" CommandName="Insert" />
    </EmptyDataTemplate>
    </asp:GridView>
    <asp:DetailsView ID="dvCategory" runat="server" Width="150px" AutoGenerateRows="false"
           AutoGenerateInsertButton="True" DataSourceID="LinqDataSource1">
    <Fields>
        <asp:TemplateField HeaderText="foo">
            <InsertItemTemplate>
                <asp:DropDownList ID="ddlCategory" runat="server" Width="150"></asp:DropDownList>
            </InsertItemTemplate>
        </asp:TemplateField>
    </Fields>
    </asp:DetailsView><asp:LinqDataSource ID="LinqDataSource1" runat="server" 
    ContextTypeName="WebApplication1.DataClasses1DataContext" 
    TableName="Categories"></asp:LinqDataSource>

Codebehind:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            this.gvCategory.DataBind();
        } 

    }

    protected void gvCategory_RowCommand(object sender, GridViewCommandEventArgs e)
    {
        if (e.CommandName == "Insert")
        {
            this.dvCategory.ChangeMode(DetailsViewMode.Insert);
            DropDownList _ddlCat = (DropDownList)this.dvCategory.FindControl("ddlCategory");
            if (_ddlCat != null)
            {
                _ddlCat.Items.Clear();
                _ddlCat.Items.Add(new ListItem() { Text = "-- empty --", Value = "-1" });
            }
        }
   }

Я также пытался использовать ItemTemplate, а не InsertItemTemplate, но это приводит к тому же. После использования ChangeMode-метода DetailsView.CurrentMode == InsertMode. Единственное, о чем я могу думать, это то, что разметка уже сгенерирована для ItemTemplate, и изменение Mode на InsertMode не может повлиять на визуализированную разметку или что-то вроде этого.

У кого-нибудь есть решение этой проблемы? =)

1 Ответ

2 голосов
/ 07 января 2010

Я думаю, вы на правильном пути. Трудно сказать, не видя весь код, но в основном каждый раз, когда вы изменяете режим рендеринга строки в элементе управления типа повторителя, вам нужно перепривязать его так, чтобы он был перерисован. Тот факт, что FindControl возвращает NULL, означает только одно: УПРАВЛЕНИЕ НЕ ТАМ. Что означает, что это не было оказано. Вы можете убедиться в этом, посмотрев на иерархию элементов управления.

Итак, в вашем обработчике отмены вы перепроверяете?

...