Почему мое событие itemCommand DataGrid срабатывает только при втором щелчке элемента в элементе управления сеткой? - PullRequest
1 голос
/ 25 марта 2019

У меня проблема с сеткой данных веб-форм, реагирующей на событие нажатия.Позвольте мне объяснить:

  1. Когда страница загружается впервые, заполняется раскрывающийся список для выбора пользователем элемента.
  2. Когда пользователь выбираетВ раскрывающемся списке появляется сетка данных (называемая tmdg) (загрузка 2-й страницы), содержащая ButtonColumns.Когда пользователь выбирает кнопку в одном из ButtonColumns в сетке данных, значение кнопки изменяется с false на true (или с true на false, в зависимости от ее начального значения).В событии Page_Load, если Page.IsPostBack == true, я назначаю обработчик событий сетке данных (tmdg) следующим образом: tmdg.ItemCommand + = Tmdg_ItemCommand;

  3. Tmdg_ItemCommand - методэто вызывает Save (), который переворачивает таблицу данных и, в конечном счете, значение ячейки сетки данных.

Это все работает для ОЧЕНЬ ПЕРВЫГО щелчка в сетке данных.ОДНАКО для последующего щелчка по сетке данных значения button.DataTextField отражаются только во ВТОРОМ щелчке сетки.(по сути, «двойной щелчок» вместо одного клика).Моя цель - отразить значение ячейки в ButtonColumn для каждого отдельного события щелчка.

Обратите внимание: после первого щелчка сетки, где значение успешно меняется, если я могу щелкнуть ячейку (5,6), где ничего не происходит, если затем я нажму ячейку (7,2), я получубросок этой клетки (7,2).Аналогично, я мог бы просто щелкнуть (5,2) еще раз, где ничего не происходит, затем снова выбрать (5,2), чтобы получить сальто.(это то, что я имею в виду, по сути, «двойной щелчок»)

Другие примечания:

  1. Я попытался назначить обработчик событий ALL OVER приложения в нескольких местах (до Page_Load в OnInit страницы, или в методе Panel_Init UpdatePanel, или независимо от того, является ли Page.IsPostBack в Page_Load или после Page_Load)

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

Я постараюсь не размещать здесь большой беспорядок кода, но хочу предоставить вам НЕЧТО.Я немного отредактировал его для краткости.

:::: Push.aspx ::::

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Push.aspx.cs" Inherits="TMUWF.Push"  MasterPageFile="~/Site.Master" %>
    <asp:Content ID="Content3" ContentPlaceHolderID="MainContent" Runat="Server">
        <asp:DropDownList ID="DropDownList1" 
            OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged"
            runat="server" 
            AutoPostBack="True"
            AppendDataBoundItems="true" 
            OnMouseDown="this.size=10;" 
            OnFocusOut="this.size=1;" 
            OnDblClick="this.size=1;"
            >
        </asp:DropDownList>

        <asp:UpdatePanel  ID="UpdatePanel1" runat="server" UpdateMode="Conditional" OnInit="Panel_Init">
            <contenttemplate>
                <h3 id="div-Col-Title">Node</h3>
                <asp:Panel runat="server" ID="Panel1">
                    <div id="div-Row-Title"><h3 >Channel</h3></div>
                </asp:Panel>
            </contenttemplate>
        </asp:UpdatePanel>
    </asp:Content>

:::: Push.aspx.cs ::::

namespace TMUWF 
{
    public partial class Push : System.Web.UI.Page
    {
        DataGrid tmdg = new DataGrid
        {
            AutoGenerateColumns = false,
            CssClass = "gvClass push"            
        };
        DataTable TraffMat = new DataTable();
        DataView TraffMatView;

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                UpdatePanel1.Visible = false;
                FillDropDown();
            }
            else if (!(Session["PushIntId"] == null))
            {
                int IntID = GetSession();
                BindGrid(IntID);

                // instead of checking for null, just remove the event handler
                tmdg.ItemCommand -= Tmdg_ItemCommand;
                // Manually register the event-handling method for the item click 
                tmdg.ItemCommand += Tmdg_ItemCommand;
            }
        }

        private void FillDropDown()
        { //redacted, pulls values from database for dropdownlist 
        }

        private void BindGrid(int IntID)
        {
            if (Panel1.Controls.Contains(tmdg))
            {
                Panel1.Controls.Remove(tmdg);
            }
            SaveSession(IntID);

            tmdg = BuildTmdg(tmdg, TraffMat);
            TraffMatView = new DataView(TraffMat);

            // Set the data source and bind to the Data Grid control.
            tmdg.DataSource = TraffMatView;
            tmdg.DataBind();

            if (!Panel1.Controls.Contains(tmdg))
            {
                Panel1.Controls.Add(tmdg);
            }
            UpdatePanel1.Visible = true;
            UpdatePanel1.Update();
        }

        private DataGrid BuildTmdg(DataGrid dg, DataTable dt)
        {
            dg.Columns.Clear();
            for (int col = 0; col<17; col++)
            {
                if (col == 0)
                {
                    BoundColumn bc = new BoundColumn
                    {
                        HeaderText = " ",
                        DataField = dt.Columns[col].ToString(),
                        ReadOnly = true
                    };
                    dg.Columns.Add(bc);
                }
                else
                {
                    ButtonColumn btnc = new ButtonColumn
                    {
                        HeaderText = col.ToString(),
                        ButtonType = ButtonColumnType.PushButton,
                        DataTextField = dt.Columns[col].ToString(),
                        CommandName = col.ToString()
                    };
                    dg.Columns.Add(btnc);
                }
            }
            return dg;
        }

        private void Tmdg_ItemCommand(object source, DataGridCommandEventArgs e)
        {
            Save((Int32)Session["PushIntID"], Convert.ToInt32(e.CommandName), e.Item.DataSetIndex+1);
        }

        private void Save(int IntID, int col, int row)
        {
            int newIntID = IntID;
            int newcol = col;
            int newrow = row;

            // Apply changes to DataTable
            string newVal = UpdateDataTable(IntID, col, row);

            // Apply changes to Database
            int rowsAffected = Apply(IntID, col, row, newVal);

            // Bind DataTable to TMDG
            BindGrid(IntID);
        }

        private string UpdateDataTable(int IntID, int col, int row)
        {
            row--;
            string val = TraffMat.Rows[row][col].ToString();
            if (val == "False")
            {
                val = "True";
                TraffMat.Rows[row][col] = val;
            }
            else
            {
                val = "False";
                TraffMat.Rows[row][col] = val;
            }
            TraffMat.AcceptChanges();
            SaveSession(IntID);
            TraffMatView = new DataView(TraffMat);
            return val;
        }

        private int Apply(int IntID, int col, int row, string NewVal)
        { //redacted, saves values to database 
        }

        protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
        { //redacted, fills DataTable from database, calls SaveSession, calls BindGrid 
        }

        private int GetSession()
        { //redacted, gets session state 
        }

        private void SaveSession(int IntID)
        { //redacted, sets session state 
        }

    }
}

Как мне кажется, когда я устанавливаю точку останова внутри обоих операторов "if" в BindGrid (), первое "если" часто пропускается, подразумевая, что Panel1 не содержит моего datagrid tmdg при этоммомент во времени.Это «если» специально пропускается в том «первом щелчке», которое игнорируется.

Пожалуйста, дайте мне знать, если вам нужна дополнительная информация от меня!Я надеюсь, что один из вас сможет понять, что я делаю неправильно !!Любые комментарии приветствуются ..

1 Ответ

0 голосов
/ 26 марта 2019

Вместо создания tmdg сетки данных в Push.aspx.cs, я добавил его в Push.aspx, и событие click срабатывает каждый раз.Я не уверен, почему это работает в .aspx, но не в файле .aspx.cs.

Далее следует новый код для объяснения ...

:::: Push.aspx:::: (сетка данных добавлена ​​здесь)

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Push.aspx.cs" Inherits="TMUWF.Push"  MasterPageFile="~/Site.Master" %>
    <asp:Content ID="Content3" ContentPlaceHolderID="MainContent" Runat="Server">
        <asp:DropDownList ID="DropDownList1" 
            OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged"
            runat="server" 
            AutoPostBack="True"
            AppendDataBoundItems="true" 
            OnMouseDown="this.size=10;" 
            OnFocusOut="this.size=1;" 
            OnDblClick="this.size=1;"
            >
        </asp:DropDownList>

        <asp:UpdatePanel  ID="UpdatePanel1" runat="server" UpdateMode="Conditional" OnInit="Panel_Init">
            <contenttemplate>
                <h3 id="div-Col-Title">Node</h3>
                <asp:Panel runat="server" ID="Panel1">
                    <div id="div-Row-Title"><h3 >Channel</h3></div>
                    <asp:DataGrid ID="tmdg" CssClass="gvClass push" AutoGenerateColumns="false" runat="server" >
                    </asp:DataGrid>
                </asp:Panel>
            </contenttemplate>
        </asp:UpdatePanel>
    </asp:Content>

:::: Push.aspx.cs :::: (сетка данных удалена здесь)

        //DataGrid tmdg = new DataGrid
        //{
        //    AutoGenerateColumns = false,
        //    CssClass = "gvClass push"            
        //};

Мысли о ПОЧЕМУ приветствуется.

...