0

通常モードでも編集モードでも、特定のセルにテキストボックスが入力される、はるかに複雑な機能セットの概念実証 (POC) GridView に取り組んでいます。特定のテキスト ボックスがフォーカス (タブまたはマウス) を受け取ると、行が編集状態に設定され、編集モードの対応するテキスト ボックスがフォーカスを受け取る必要があります。そのテキストボックスがフォーカスを失うと、その行が更新されますライフサイクルの問題であると思われるフォーカスを受け取った列 (「テキストボックス」) を選択する実行可能な方法を見つけることを除いて、POC は機能していますが、適切な回避策は思いつきません。これは POC であることを覚えておいてください。これを機能させるための迅速で汚れた方法として、ベスト プラクティスではないかもしれないことを私が行ったことがあります。提案をいただければ幸いです。

形:

<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="StandardContactEditor.aspx.vb" Inherits="EditableGridView.StandardContactEditor" EnableEventValidation="false" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:GridView ID="contactsDataGrid"
                    AllowPaging="true" PageSize="5"
                    DataKeyNames="ID"
                    AutoGenerateColumns="false"

                    runat="server">
                <Columns>
                    <asp:TemplateField HeaderText="First Name">
                        <ItemTemplate>
                            <asp:TextBox ID="txtFirstName" Text='<%# Bind("FirstName") %>' runat="server" />
                        </ItemTemplate>
                        <EditItemTemplate>
                            <asp:TextBox ID="txtFirstNameEdit" Text='<%# Bind("FirstName") %>' runat="server" />
                        </EditItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="Last Name">
                        <ItemTemplate>
                            <asp:TextBox ID="txtLastName" Text='<%# Bind("LastName") %>' runat="server" />
                        </ItemTemplate>
                        <EditItemTemplate>
                            <asp:TextBox ID="txtLastNameEdit" Text='<%# Bind("LastName") %>' runat="server" />
                        </EditItemTemplate>
                    </asp:TemplateField>
                </Columns>
            </asp:GridView>
        </div>
    </form>
</body>
</html>

コード:

Imports FileHelpers

Public Class StandardContactEditor
    Inherits System.Web.UI.Page

    private fileName As String = "C:\TestFiles\TestContacts.csv"
    Private records As List(Of ContactCSV)

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Not IsPostBack
            BindGridData()
        End If
    End Sub

    Private Sub BindGridData()
        PopulateRecords()

        Me.contactsDataGrid.DataSource = records
        Me.contactsDataGrid.DataBind()
    End Sub

    Protected Sub RowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs) Handles contactsDataGrid.RowDataBound
        e.Row.Attributes("onfocus") = ClientScript.GetPostBackClientHyperlink(contactsDataGrid, "Edit$" + e.Row.DataItemIndex.ToString(), false)

        If Not ((e.Row.RowState = DataControlRowState.Edit) _
                Or (e.Row.RowState = (DataControlRowState.Alternate Or DataControlRowState.Edit)))
            Try
                ' First Name Column
                Dim firstNameTb As TextBox = e.Row.FindControl("txtFirstName")
                ' firstNameTb.Attributes("onfocus") = ClientScript.GetPostBackClientHyperlink(contactsDataGrid, "Edit$" + e.Row.DataItemIndex.ToString(), false)

                                    ' ISSUE CAUSED BY APPENDING "000" - Used for col/textbox identification
                firstNameTb.Attributes("onfocus") = ClientScript.GetPostBackClientHyperlink(contactsDataGrid, "Edit$" + e.Row.DataItemIndex.ToString() + "000", false)
            Catch ex As Exception
                Console.WriteLine()
            End Try

            Try
                Dim lastNameTb As TextBox = e.Row.FindControl("txtLastName")
                ' lastNameTb.Attributes("onfocus") = ClientScript.GetPostBackClientHyperlink(contactsDataGrid, "Edit$" + e.Row.DataItemIndex.ToString(), false)

                                    ' ISSUE CAUSED BY APPENDING "001" - Used for col/textbox identification
                lastNameTb.Attributes("onfocus") = ClientScript.GetPostBackClientHyperlink(contactsDataGrid, "Edit$" + e.Row.DataItemIndex.ToString() + "001", false)
            Catch ex As Exception
            End Try
        End If
    End Sub

    Protected Sub RowEditing(ByVal sender As Object, ByVal e As GridViewEditEventArgs) Handles contactsDataGrid.RowEditing
        contactsDataGrid.EditIndex = (e.NewEditIndex / 1000)
        Dim col As Integer = (e.NewEditIndex Mod 1000)

        ' contactsDataGrid.EditIndex = e.NewEditIndex

        BindGridData()

        Dim fntb As TextBox = contactsDataGrid.Rows(contactsDataGrid.EditIndex).FindControl("txtFirstNameEdit")
        fntb.Attributes("onblur") = ClientScript.GetPostBackClientHyperlink(contactsDataGrid, "Update$" + contactsDataGrid.EditIndex.ToString(), false)
        ' fntb.Focus()

        Dim lntb As TextBox = contactsDataGrid.Rows(contactsDataGrid.EditIndex).FindControl("txtLastNameEdit")
        lntb.Attributes("onblur") = ClientScript.GetPostBackClientHyperlink(contactsDataGrid, "Update$" + contactsDataGrid.EditIndex.ToString(), false)
        ' lntb.Focus()

        If(col = 0)
            fntb.Focus()
        Else If(col = 1)
            lntb.Focus()
        End If
    End Sub

    Protected Sub RowUpdating(ByVal sender As Object, ByVal e As GridViewUpdateEventArgs) Handles contactsDataGrid.RowUpdating
                    ' AT THIS POINT THE EDIT FIELDS ARE NOT VISIBLE AND AN EXCEPTION IS THROWN WHEN TRYING TO RETRIEVE THOSE TEXTBOXES

        ' Trying to override here
        contactsDataGrid.EditIndex = (contactsDataGrid.EditIndex / 1000)

        PopulateRecords()

        Dim id As String = contactsDataGrid.DataKeys(e.RowIndex).Value.ToString()

        Dim record As ContactCSV = records.Where(Function(x) x.ID = id).SingleOrDefault()

        Dim firstNameTb As TextBox = contactsDataGrid.Rows(e.RowIndex).FindControl("txtFirstNameEdit")
        record.firstName = firstNameTb.Text

        Dim lastNameTb As TextBox = contactsDataGrid.Rows(e.RowIndex).FindControl("txtLastNameEdit")
        record.lastName = lastNameTb.Text

        WriteRecordsToFile()

        contactsDataGrid.EditIndex = -1

        ' update the actual data
        contactsDataGrid.DataSource = records
        contactsDataGrid.DataBind()
    End Sub

    Protected Sub SelectedColumn(ByVal Sender As Object, ByVal e As EventArgs)
        Console.WriteLine()
    End Sub

    Private Sub PopulateRecords()
        Dim fileEngine As New FileHelperEngine(GetType(ContactCSV))

        Try
            Dim objs As ContactCSV() = fileEngine.ReadFile(fileName)
            records = objs.ToList()
        Catch ex As exception

        End Try
    End Sub

    Private Sub WriteRecordsToFile()
        Dim fileEngine As New FileHelperEngine(GetType(ContactCSV))

        fileEngine.WriteFile(fileName, records)
    End Sub
End Class
4

1 に答える 1

1

これは、なじみのないテクノロジーを組み合わせてソリューションを考えすぎる典型的なケースでした。アイデアは、応答性の高い (フィールド編集ごとの) ページを構築することでした。組み込みの GridView 機能を混在させるのではなく、単純な OnTextChanged が期待どおりに機能し、他のすべてが取り除かれました。投稿された前のコードで判明した問題は、OnBlur の後で、列識別部分が配置され、行が Alternate Or Edit 状態ではなく Alternate 状態に設定されたことです。

形:

<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="StandardContactEditor.aspx.vb" Inherits="EditableGridView.StandardContactEditor" EnableEventValidation="true" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:GridView ID="contactsDataGrid"
                    AllowPaging="true" PageSize="5"
                    DataKeyNames="ID"
                    AutoGenerateColumns="false"

                    runat="server">
                <Columns>
                    <asp:TemplateField HeaderText="First Name">
                        <ItemTemplate>
                            <asp:TextBox ID="txtFirstName" Text='<%# Bind("FirstName") %>' OnTextChanged="textBox_TextChanged" AutoPostBack="true" runat="server" />
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="Last Name">
                        <ItemTemplate>
                            <asp:TextBox ID="txtLastName" Text='<%# Bind("LastName") %>' OnTextChanged="textBox_TextChanged" AutoPostBack="true" runat="server" />
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="Phone Number">
                        <ItemTemplate>
                            <asp:TextBox ID="txtPhoneNumber" Text='<%# Bind("PhoneNumber") %>' OnTextChanged="textBox_TextCHanged" AutoPostBack="true" runat="server" />
                        </ItemTemplate>
                    </asp:TemplateField>
                </Columns>
            </asp:GridView>
        </div>
    </form>
</body>
</html>

コード:

Imports FileHelpers

Public Class StandardContactEditor
    Inherits System.Web.UI.Page

    private fileName As String = "C:\TestFiles\TestContacts.csv"
    Private records As List(Of ContactCSV)

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Not IsPostBack
            BindGridData()
        End If
    End Sub

    Private Sub BindGridData()
        PopulateRecords()

        Me.contactsDataGrid.DataSource = records
        Me.contactsDataGrid.DataBind()
    End Sub

    Protected Sub textBox_TextChanged(ByVal sender As Object, ByVal e As EventArgs)
        PopulateRecords()

        Dim tb as TextBox = sender
        Dim row As GridViewRow = tb.Parent.Parent

        Dim record As ContactCSV = records.Where(Function(x) x.ID = row.RowIndex).SingleOrDefault()

        Dim firstNameTb As TextBox = contactsDataGrid.Rows(row.RowIndex).FindControl("txtFirstName")
        record.firstName = firstNameTb.Text

        Dim lastNameTb As TextBox = contactsDataGrid.Rows(row.RowIndex).FindControl("txtLastName")
        record.lastName = lastNameTb.Text

        Dim phoneNumberTb As TextBox = contactsDataGrid.Rows(row.RowIndex).FindControl("txtPhoneNumber")
        record.PhoneNumber = phoneNumberTb.Text

        WriteRecordsToFile()
    End Sub

    Private Sub PopulateRecords()
        Dim fileEngine As New FileHelperEngine(GetType(ContactCSV))

        Try
            Dim objs As ContactCSV() = fileEngine.ReadFile(fileName)
            records = objs.ToList()
        Catch ex As exception

        End Try
    End Sub

    Private Sub WriteRecordsToFile()
        Dim fileEngine As New FileHelperEngine(GetType(ContactCSV))

        fileEngine.WriteFile(fileName, records)
    End Sub
End Class
于 2013-04-17T14:05:23.177 に答える