Вопрос

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

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

Это отлично работает до тех пор, пока пользователь сделал выбор из окна списка . Если у них нет, метод LoadPostdata () не вызывается, и, следовательно, новая коллекция listitem не создается. (Я установил это, используя отладчик.)

Я предполагаю, что метод LoadPostData вызывается только в том случае, если в атрибуте UniqueId (I.E. «Имя» в формате UniqueiD (I.E. 'noam) включает в себя данные. Если пользователь не сделал выбор из окна списка, ничто не включено в данные по сообщениям для UniqueId и LoadPostData в списке () не вызывается. Это правильно?

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

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

Дэвид

Это было полезно?

Решение 3

Я установил, что метод LoadPostData () не вызывается, если данные Post не содержит элемент с тем же именем, что и уникальный элемент управления. [Редактировать: вызов страницы. Регистрацияrequirespostback во время init () преодолевает это.] Я вижу почему, но это вполне ограничивает.

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

Две вещи должны иметь в виду, когда используете этот подход:

1) У вас больше нет доступа к объекту neadcollection namevaluecollection, который передается в метод LoadPostdata () в качестве аргумента. Это означает, что вы должны извлечь почтовые данные из коллекции request.form, что немного сложнее. 2) Поскольку onload () возникает после того, как код обработки ViewState вам нужно будет вручную установить выбранный сигнал после создания listiTems. Если вы этого не сделаете, если список ListBox заполнен через AJAX, и пользователь делает выбор, выбор будет потерян.

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

Другие советы

Я немного поздно прыгнул в этом, но, просто для дальнейшего использования, вот как я достиг что-то похожее ...

Мой контроль - это дерево, которое использует шаблоны для узлов. Проблема, в которой я имел дело с этим, заключался в том, как запечатлеть на стороне клиента изменения в расширенное / рухнутое состояние узлов. Что закончилось работать:

в CreateChildControls Добавьте скрытое поле в коллекцию элементов управления My root Control.

protected override int CreateChildControls(IEnumerable dataSource, bool dataBinding)
{
    ...
    _cdExpanded = new HiddenField();
    _cdExpanded.ID = "cdExpanded";
    this.Controls.Add(_cdExpanded);
    ...
}
.

в Oninit Call

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

в LoadPostdata Ищите значение в почтовом сборе, соответствующем UniqueId (не клиенту) скрытого поля:

public bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
{
    ...
    string cdExpanded = postCollection[_cdExpanded.UniqueID];
    ...
}
.

В классах для отдельных узлов у меня есть код, который заполняет события OnClick моих кнопок переключателей с вызовом на функцию JavaScript, которая принимает идентификатор базового управления и отдельные узлы в качестве аргументов.

    string ToggleScript
    {
        get
        {
            return "ToggleNode('" + this.ClientID + "', '" + _TreeRoot.ClientID + "');";
        }
    }
    protected override void Render(HtmlTextWriter writer)
    {
        ...
        if (this.HasChildren)
        {
            writer.AddAttribute("onclick", ToggleScript);
        }
        ...
    }
.

Это делает его, чтобы найти скрытое поле довольно легко через GetElementById:

function ToggleNode(nodeID, treeID) {
var cdExpanded = document.getElementById(treeID + "_cdExpanded");
...
}
.

JavaScript затем изменяет значение скрытого поля по мере необходимости для события, произошедшего. Когда мы вернемся к серверу, я могу выбрать содержимое этого поля и изменять состояние управления по мере необходимости до того, как он снова отображается. (Примечание. На самом деле я использую 3 скрытых поля для отслеживания разных событий, но концепция одинакова)

Надеюсь, это помогает другим в будущем ...

звучит очень странно работать только при выборе элемента.Быстрый способ проверить, вызывается ли 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>
.

Когда вы нажимаете на ходу, вы должны увидеть «LoadPostdata» в след.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top