Пользовательский элемент управления ASP.NET: когда LoadPostData () назван?

Я разработал пользовательский элемент управления, который расширяет ListBox. Идея состоит в том, что управление 'помнит' модификации к своим элементам, которые произошли клиентские, например, в результате запроса Ajax.

Путем это работает, то, что управление также представляет скрытый вход, и результат запроса Ajax хранится в скрытом входе. Это отправляется назад, и LoadPostData управления (), метод ищет скрытый вход, и если скрытый вход имеет данные, создает набор ListItem из него.

Это работает отлично, пока пользователь сделал выбор от поля списка. Если они не имеют, LoadPostData (), метод не становится названным, и следовательно новый набор ListItem не создается. (Я установил это использование отладчика.)

Я предполагаю, что метод LoadPostData только называют, если сбор данных POST включает данные, соответствующие UniqueID управления (т.е. атрибут 'имени' в HTML). Если пользователь не сделал выбор от поля списка, ничто не включено в данные сообщения для UniqueID поля списка, и LoadPostData () не называют. Это корректно?

Кто-либо может предложить, как я могу удостовериться, что LoadPostData моего пользовательского ListBox () метод называют каждой обратной передачей независимо от того, сделал ли пользователь выбор?

Заранее спасибо - я действительно застреваю с этим.

David

7
задан David 9 July 2010 в 09:00
поделиться

2 ответа

Я установил, что метод LoadPostData () не вызывается, если данные сообщения не содержат элемент с тем же именем, что и UniqueID элемента управления. [Изменить: вызов Page.RegisterRequiresPostback во время Init () преодолевает это.] Я понимаю, почему, но это довольно ограничивает.

Я решил проблему, не решив ее вообще в методе LoadPostData (). Вместо этого я обработал это в методе, который вместо этого вызываю в OnLoad ().

При использовании этого подхода необходимо учитывать две вещи:

1) У вас больше нет доступа к объекту postCollection NameValueCollection, который передается методу LoadPostData () в качестве аргумента. Это означает, что вам нужно извлечь данные публикации из коллекции Request.Form, что немного сложнее.2) Поскольку OnLoad () происходит после кода обработки ViewState, вам нужно будет вручную установить SelectedValue после создания ListItems. В противном случае, если список заполняется через AJAX и пользователь делает выбор, выбор будет утерян.

Надеюсь, это кому-то поможет в будущем.

1
ответ дан 6 December 2019 в 21:09
поделиться

Звучит очень странно, если он работает только тогда, когда элемент выбран. Быстрый способ проверить, вызывается ли LoadPostData, - включить трассировку и поместить в IPostBackDataHandler.LoadPostData(...) следующее.

Page.Trace.Write("My control", "LoadPostData");

Если это так, вы должны убедиться, что у вас получилось следующее:

Page.RegisterRequiresPostBack(this) in OnInit

Вот полный пример элемента управления.

using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel.Design;
using System.ComponentModel;
using System.Web.UI.Design;

namespace Controls
{
    public sealed class ExtendedListBoxDesigner : ControlDesigner
    {

        public override string GetDesignTimeHtml()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<div>My designer</div>");
            return sb.ToString();
        }

    }

    [DesignerAttribute(typeof(ExtendedListBoxDesigner), typeof(IDesigner))]
    public class ExtendedListBox : ListBox, INamingContainer, IPostBackDataHandler 
    {
        bool IPostBackDataHandler.LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
        {
            Page.Trace.Write("ExtendedListBox", "LoadPostData");
            return true;
        }


        protected override void OnInit(EventArgs e)
        {
            Page.RegisterRequiresPostBack(this);
            base.OnInit(e);
        }

        protected override void RenderContents(HtmlTextWriter writer)
        {
            base.RenderContents(writer);
            writer.Write(string.Format("<input type=\"hidden\" name=\"{0}_dummy\" value=\"alwaysPostBack\">", this.ID));
        }

    }
}

и страница выглядит следующим образом.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="ControlSamlpe._Default" Trace="true" %>
<%@ Register Assembly="Controls" Namespace="Controls" TagPrefix="sample" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <sample:ExtendedListBox runat="server" ID="extListBox"></sample:ExtendedListBox>
    <asp:Button runat="server" ID="go" />
    </div>
    </form>
</body>
</html>

Когда вы нажимаете на кнопку go, вы должны увидеть "LoadPostData" в трассировке.

3
ответ дан 6 December 2019 в 21:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: