О том, как выполнять обратную передачу вручную, передавать объекты и вызывать события в пользовательских элементах управления ASP.NET. - PullRequest
1 голос
/ 05 мая 2011

Я пытаюсь создать собственный календарь в качестве пользовательского элемента управления ASP.NET 4 для выполнения многих сложных задач (я не нашел в сети ничего подходящего для моих нужд).

Мне удалосьсоздать календарь, передать существующие события, обработать несколько типов событий и прочее.

Чего я не могу сделать, так это, когда пользователь нажимает на день, переходить на страницу, содержащую пользовательский элемент управления a DateTime с указанным днем.

Моя проблема заключается в том, что в моем пользовательском элементе управления (например, LinkButton s) нет веб-элементов управления, календарь равен <table />, а каждый день - <td />поэтому мне приходится вручную поднимать постбэки, когда пользователь нажимает на <td />.

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

Основные вещи, которые мне нужно понять:

  1. Как передать DateTime вместе с обратной передачей (если это правильно)?Метод ClientScriptManager.GetPostBackEventReference ожидает в качестве второго параметра String, а не объекта.

  2. Как я могу реализовать поведение, подобное тому, которое демонстрирует DropDownList 'OnSelectedIndexChangedсобытие?Я имею в виду, что что-то вроде моего пользовательского элемента управления объявляет событие DayClicked, которое возникает, когда пользователь нажимает на <td /> дня, который я потребляю на странице, реализующей элемент управления.

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

Здесь будет codez

Этократкий пример (без всего, что мне нужно, но не имеет отношения к достижению цели) того, что у меня есть прямо сейчас.

Example.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="Example.ascx.cs" Inherits="ExampleControl" %>

<asp:PlaceHolder ID="Content" runat="server" />

Example.ascx.cs

using System;
using System.Drawing;
using System.Globalization;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class ExampleControl : UserControl
{
    public Int32 Year { get; set; }

    public Int32 Month { get; set; }

    protected void Page_Load(Object sender, EventArgs e)
    {
        // If the year has not been set.
        if (this.Year == 0)
        {
            // Set the year to the current year.
            this.Year = DateTime.Today.Year;
        }

        // If the month has not been set.
        if (this.Month == 0)
        {
            // Set the month to the current month.
            this.Month = DateTime.Today.Month;
        }

        // Create the calendar table.
        Table calendar = new Table();

        // Display grid.
        calendar.GridLines = GridLines.Both;

        // Create the calendar header (a row with the name of the days).
        TableRow calendarHeader = new TableRow();

        // Place the header in thead instead of tbody.
        calendarHeader.TableSection = TableRowSection.TableHeader;

        // Add the days of the week.
        for (Int32 dayOfWeek = 0; dayOfWeek < 7; dayOfWeek++)
        {
            // Create the cell for the day.
            TableCell dayHeader = new TableCell();

            // Set the name of the day using the current UI culture.
            dayHeader.Text = CultureInfo.CurrentUICulture.DateTimeFormat.GetAbbreviatedDayName((DayOfWeek) dayOfWeek);

            // Add the day to the header.
            calendarHeader.Cells.Add(dayHeader);
        }

        // Add the header to the calendar.
        calendar.Rows.Add(calendarHeader);

        // Create the row for the first week.
        TableRow weekRow = new TableRow();

        // Add the days of the month.
        for (DateTime day = new DateTime(this.Year, this.Month, 1); day.Year == this.Year && day.Month == this.Month; day = day.AddDays(1))
        {
            // If it's the first day of the month.
            if (day.Day == 1)
            {
                // Place enough spacers to have the first day under the right day of the week.
                for (Int32 spacer = 0; spacer < (Int32) day.DayOfWeek; spacer++)
                {
                    // Add the spacer to the week.
                    weekRow.Cells.Add(new TableCell());
                }
            }

            // If it's a new week.
            if (day.Day != 1 && day.DayOfWeek == DayOfWeek.Sunday)
            {
                // Add the previous week to the calendar.
                calendar.Rows.Add(weekRow);

                // Create a new row for the new week.
                weekRow = new TableRow();
            }

            // Create the cell for the day.
            TableCell dayCell = new TableCell();

            // When the user clicks the cell do a postback.
            dayCell.Attributes.Add("onclick", this.Page.ClientScript.GetPostBackEventReference(this, "DayClicked"));

            // Display the day of the month.
            dayCell.Text = Convert.ToString(day.Day);

            // Add the day to the week.
            weekRow.Cells.Add(dayCell);

            // If it's the last day of the month.
            if (day.Day == DateTime.DaysInMonth(this.Year, this.Month))
            {
                // Place enough spacers to fill up the week.
                for (Int32 spacer = (Int32) day.DayOfWeek; spacer < 6; spacer++)
                {
                    // Add the spacer to the week.
                    weekRow.Cells.Add(new TableCell());
                }
            }
        }

        // Add the last week to the calendar.
        calendar.Rows.Add(weekRow);

        // Add the calendar to the control.
        this.Content.Controls.Add(calendar);
    }
}

Example.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Example.aspx.cs" Inherits="ExamplePage" %>
<%@ Register Src="~/Example.ascx" TagPrefix="ex" TagName="Calendar" %>

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title>Example</title>
    </head>
    <body>
        <form runat="server">
            <asp:ScriptManager ID="ScriptManager" runat="server" />
            <h1>Example</h1>
            <asp:UpdatePanel ID="UpdatePanel" runat="server">
                <ContentTemplate>
                    <ex:Calendar ID="Calendar" Year="2011" Month="3" runat="server" />
                </ContentTemplate>
            </asp:UpdatePanel>
        </form>
    </body>
</html>

Example.aspx.cs

using System;
using System.Web.UI;

public partial class ExamplePage : Page
{
    protected void Page_Load(Object sender, EventArgs e)
    {
    }
}

1 Ответ

0 голосов
/ 14 августа 2011

Один из вариантов: клиентский скрипт обновит скрытое поле с указанием дня, по которому был выполнен щелчок, прежде чем вызывать код для обратной отправки.Затем вы сможете получить значение из скрытого поля на сервере.

При таком подходе вы не будете пропускать день, в котором щелкали аргументы обратной передачи.Таким образом, вы можете вызвать GetPostBackEventReference без пользовательских аргументов.

Лично я бы предпочел создать его как пользовательский серверный элемент управления вместо пользовательского.Вы можете реализовать IPostBackDataHandler .В методе LoadPostData, если значение скрытого поля изменилось, вы бы вернули True, что заставило бы .net вызвать метод RaisePostDataChangedEvent, который вы бы закодировали с помощью метода, который вызовет ваше измененное событие.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...