Click here to Skip to main content
15,892,005 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi.

I have created a control that looks a bit like a Listbox but allows items to be dragged and dropped to and from other similar controls.

I have just added a postback event so that I can use the dropped item information in a serverside event, which works great.

My issue is that these controls will almost exclusivity be contained within an updated panel.

My issue is that my control always performs a full postback. In fact, I know that my code tells it to. My issue is that I have no idea how Async postback controls are written. All the examples I can find online talk about controls inherited from buttons or other controls that are already set up. This is now useful when writing controls from scratch.

Please advise me on how to manage postbacks from within update panels.

Here is some code ^_^

custome.dragdrop.list.js:
JavaScript
StartupFunctions.push(function () {
    var dragdropLists = $('.custom-dragdrop-list');

    $.each(dragdropLists, function () {
        var list = this;
        $(list).find("li").click(function () {
            $(list).find("li").removeClass('selected');
            if (!$(this).hasClass('selected'))
                $(this).addClass('selected');
        });
    });
});



function allowDrop(e) {
    e = e || window.event;
    e.preventDefault();
}

function drag(e) {
    e = e || window.event;
    $(e.target).removeClass('selected');
    e.dataTransfer.setData("text", e.target.id);
}

function drop(e, target) {
    e = e || window.event;
    e.preventDefault();
    var data = e.dataTransfer.getData("text");
    $(target).find("ul").append(document.getElementById(data));

    __doPostBack($(target).attr('id'), $("li[id='" + data + "']").val());
}


DragDropPanel.cs
C#
public class DragDropListBoxEventArgs : EventArgs
{
    public DragDropListBoxEventArgs(string itemDropped)
    {
        ItemDropped = itemDropped;
    }
    public string ItemDropped { get; set; }
}

public delegate void DragDropListBoxEventHandler(DragDropListBox sender, DragDropListBoxEventArgs args);
public class DragDropListBox : ListControl, IPostBackEventHandler
{
    protected const string VpnlDragDropJsToolsName = "vpnlDragDropJsToolsName";
    protected const string VpnlDragDropJsToolsUrl = "/Resources/js/custom.dragdrop.list.js";

    public string Label { get; set; }

    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        RegisterScripts();
    }

    protected virtual void RegisterScripts()
    {
        Type cstype = Page.GetType();

        ClientScriptManager cs = Page.ClientScript;

        if (!cs.IsClientScriptIncludeRegistered(cstype, VpnlDragDropJsToolsName))
            cs.RegisterClientScriptInclude(cstype, VpnlDragDropJsToolsName, VpnlDragDropJsToolsUrl);
    }


    public event DragDropListBoxEventHandler ItemDropped;

    protected virtual void OnItemDropped(DragDropListBoxEventArgs args)
    {
        if (ItemDropped != null)
            ItemDropped(this, args);
    }

    public void RaisePostBackEvent(string eventArgument)
    {
        OnItemDropped(new DragDropListBoxEventArgs(eventArgument));
    }


    [DefaultValue(ListSelectionMode.Single)]
    public virtual ListSelectionMode SelectionMode
    {
        get
        {
            object obj = this.ViewState["SelectionMode"];
            if (obj != null)
            {
                return (ListSelectionMode)obj;
            }
            return ListSelectionMode.Single;
        }
        set
        {
            if (value < ListSelectionMode.Single || value > ListSelectionMode.Multiple)
            {
                throw new ArgumentOutOfRangeException("value");
            }
            this.ViewState["SelectionMode"] = value;
        }
    }
    [DefaultValue(4)]
    public virtual int Rows
    {
        get
        {
            object obj = this.ViewState["Rows"];
            if (obj != null)
            {
                return (int)obj;
            }
            return 4;
        }
        set
        {
            if (value < 1)
            {
                throw new ArgumentOutOfRangeException("value");
            }
            this.ViewState["Rows"] = value;
        }
    }

    public string TargetClientId { get; set; }
    public string IsTargetForClientId { get; set; }

    protected override void AddAttributesToRender(HtmlTextWriter writer)
    {
        writer.AddAttribute(HtmlTextWriterAttribute.Size, this.Rows.ToString(NumberFormatInfo.InvariantInfo));

        writer.AddAttribute(HtmlTextWriterAttribute.Name, UniqueID);

        base.AddAttributesToRender(writer);
    }

    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);
        if (this.Page != null && this.SelectionMode == ListSelectionMode.Multiple && this.Enabled)
        {
            this.Page.RegisterRequiresPostBack(this);
        }
    }

    protected override void Render(HtmlTextWriter writer)
    {
        if (!string.IsNullOrEmpty(IsTargetForClientId))
        {
            writer.AddAttribute("ondrop", "drop(event,this)");
            writer.AddAttribute("ondragover", "allowDrop(event)");
        }

        writer.AddAttribute("id", UniqueID);
        writer.AddAttribute("class","custom-dragdrop");
        writer.RenderBeginTag("div");

        if(!Label.IsEmpty())
            RenderHeader(writer);

        RenderBody(writer);

        writer.RenderEndTag();

    }

    private void RenderHeader(HtmlTextWriter writer)
    {
        writer.AddAttribute("class", "custom-list-header");
        writer.RenderBeginTag("div");

        RenderLabel(writer);

        writer.RenderEndTag();

    }

    private void RenderLabel(HtmlTextWriter writer)
    {
        writer.RenderBeginTag("Label");
        writer.Write(Label);
        writer.RenderEndTag();
    }

    private void RenderBody(HtmlTextWriter writer)
    {
        writer.AddAttribute("class", "custom-list-body");
        writer.RenderBeginTag("div");

        RenderList(writer);

        writer.RenderEndTag();
    }

    private void RenderList(HtmlTextWriter writer)
    {
        writer.AddAttribute("class", "custom-dragdrop-list");
        writer.RenderBeginTag("ul");

        RenderListItems(writer);

        writer.RenderEndTag();
    }

    private void RenderListItems(HtmlTextWriter writer)
    {
        ListItemCollection listItemCollection = this.Items;
        int count = listItemCollection.Count;

        if (count > 0)
        {
            bool flag = false;
            for (int i = 0; i < count; i++)
            {
                ListItem listItem = listItemCollection[i];
                if (listItem.Enabled)
                {
                    writer.WriteBeginTag("li");
                    writer.WriteAttribute("id", string.Format("{0}_{1}", UniqueID, listItem.Value));
                    if (listItem.Selected)
                    {
                        if (flag)
                        {
                            this.VerifyMultiSelect();
                        }
                        flag = true;
                        writer.WriteAttribute("selected", "selected");
                    }
                    writer.WriteAttribute("value", listItem.Value, true);
                    //if (listItem.HasAttributes)
                    //{
                    //    listItem.Attributes.Render(writer);
                    //}
                    if (this.Page != null)
                    {
                        this.Page.ClientScript.RegisterForEventValidation(this.UniqueID, listItem.Value);
                    }
                    writer.WriteAttribute("draggable", "true");
                    writer.WriteAttribute("ondragstart", "drag(event)");
                    writer.Write('>');
                    HttpUtility.HtmlEncode(listItem.Text, writer);
                    writer.WriteEndTag("li");
                    writer.WriteLine();
                }
            }
        }
    }

}


Let me know if you need more.

Thanks ^_^
Posted

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900