0

I've been trying to make use of DetailsView for the past few days to show and edit data from a single record taken from a GridView, both read their datafrom an SqlDataSource.

I've been searching the internet and the MSDN for info about how to use a DetailsView to edit data and I managed to cobble something together, the problem is that apparently the actual updating method doesn't run.

So here's an extract of my code

GridView In the page:

                <asp:DetailsView ID="DetailsView1" runat="server" Height="50px" Width="125px" AutoGenerateRows="False" DefaultMode="Edit">
                    <fields>
                        <asp:TemplateField HeaderText="Codice Cliente">
                            <ItemTemplate>
                                <asp:Label ID="lblCliCod" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.cli_cod") %>'></asp:Label>
                            </ItemTemplate>
                            <EditItemTemplate>
                                <asp:TextBox ID="txtCliCod" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.cli_cod")%>'></asp:TextBox>
                            </EditItemTemplate>
                        </asp:TemplateField>

                        <asp:TemplateField HeaderText="Descrizione">
                            <ItemTemplate>
                                <asp:Label ID="lblCliDesc" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.cli_desc")%>'></asp:Label>
                            </ItemTemplate>
                            <EditItemTemplate>
                                <asp:TextBox ID="txtCliDesc" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.cli_desc")%>'></asp:TextBox>
                            </EditItemTemplate>
                        </asp:TemplateField>

                        <asp:TemplateField HeaderText="Nome Utente">
                            <ItemTemplate>
                                <asp:Label ID="lblCliUser" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.cli_user")%>'></asp:Label>
                            </ItemTemplate>
                            <EditItemTemplate>
                                <asp:TextBox ID="txtCliUser" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.cli_user")%>'></asp:TextBox>
                            </EditItemTemplate>
                        </asp:TemplateField>

                        <asp:TemplateField HeaderText="Password">
                            <ItemTemplate>
                                <asp:Label ID="lblCliPass" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.cli_pass")%>'></asp:Label>
                            </ItemTemplate>
                            <EditItemTemplate>
                                <asp:TextBox ID="txtCliPass" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.cli_pass")%>'></asp:TextBox>
                            </EditItemTemplate>
                        </asp:TemplateField>

                        <asp:TemplateField HeaderText="Amministratore">
                            <ItemTemplate>
                                <asp:Label ID="lblCliAdmin" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.cli_admin")%>'></asp:Label>

                            </ItemTemplate>
                            <EditItemTemplate>
                                <asp:CheckBox ID="chkCliAdminE" runat="server" Text='<%# CBool(DataBinder.Eval(Container, "DataItem.cli_admin"))%>' />
                            </EditItemTemplate>
                        </asp:TemplateField>

                        <asp:TemplateField>
                            <EditItemTemplate>

                                <asp:LinkButton Text="Aggiorna" ID="UpdateButton" runat="Server" CommandName="Update"></asp:LinkButton>
                                <asp:LinkButton Text="Elimina" ID="DeleteButton" runat="server" CommandName="Edit"></asp:LinkButton>
                            </EditItemTemplate>
                        </asp:TemplateField>
                    </fields>
                </asp:DetailsView>

Relevant parts of the Codebehind:

Private Sub SetupDataSource() 'this is the sqldatasource I'm using for the detailsview

    SqlDataSource2.ConnectionString = Assist.connectionString
    SqlDataSource2.SelectCommand = detailsSelect
    SqlDataSource2.SelectParameters.Add(New Parameter("id"))

    SqlDataSource2.UpdateCommand = detailsUpdate
    SqlDataSource2.UpdateParameters.Add(New Parameter("cli_cod"))
    SqlDataSource2.UpdateParameters.Add(New Parameter("cli_desc"))
    SqlDataSource2.UpdateParameters.Add(New Parameter("cli_user"))
    SqlDataSource2.UpdateParameters.Add(New Parameter("cli_pass"))
    SqlDataSource2.UpdateParameters.Add(New Parameter("cli_admin"))

End Sub

Private Sub SetupDetailsView(id As Int32)
    DetailsView1.AutoGenerateRows = False
    DetailsView1.DataSource = SqlDataSource2

    SqlDataSource2.SelectParameters("id").DefaultValue = id

End Sub

Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
    cn.Open()
    SetupDataSource()

   If Not IsPostBack Then
        Dim id As String = Request.QueryString("id")
        If id <> "" Then

            SetupDetailsView(id)
            DetailsView1.DataBind()
        End If
    End If
End Sub

    Protected Sub DetailsView1_ItemUpdating(sender As Object, e As DetailsViewUpdateEventArgs) Handles DetailsView1.ItemUpdating
    Dim cliCod As String = (CType(DetailsView1.FindControl("txtCliCod"), TextBox)).Text.ToString()
    Dim cliDesc As String = (CType(DetailsView1.FindControl("txtCliDesc"), TextBox)).Text.ToString()
    Dim cliUser As String = (CType(DetailsView1.FindControl("txtCliUser"), TextBox)).Text.ToString()
    Dim cliPass As String = (CType(DetailsView1.FindControl("txtCliPass"), TextBox)).Text.ToString()
    Dim cliAdmin As Boolean = If((CType(DetailsView1.FindControl("chkCliAdminE"), CheckBox)).Checked = True, True, False)

    SqlDataSource2.UpdateParameters("cli_cod").DefaultValue = cliCod
    SqlDataSource2.UpdateParameters("cli_desc").DefaultValue = cliDesc
    SqlDataSource2.UpdateParameters("cli_user").DefaultValue = cliUser
    SqlDataSource2.UpdateParameters("cli_pass").DefaultValue = cliPass
    SqlDataSource2.UpdateParameters("cli_Admin").DefaultValue = If(cliAdmin = True, "1", "0")


    DetailsView1.DataBind()
End Sub

I'm either missing something or doing it wrong somewhere, which one is it and why?

MaddoScientisto
  • 189
  • 4
  • 17

2 Answers2

0

I'm not an expert at using SqlDataSource, but you might try inserting a SqlDataSource.Update in your Item_Updating method:

SqlDataSource2.UpdateParameters("cli_cod").DefaultValue = cliCod
SqlDataSource2.UpdateParameters("cli_desc").DefaultValue = cliDesc
SqlDataSource2.UpdateParameters("cli_user").DefaultValue = cliUser
SqlDataSource2.UpdateParameters("cli_pass").DefaultValue = cliPass
SqlDataSource2.UpdateParameters("cli_Admin").DefaultValue = If(cliAdmin = True, "1", "0")

SqlDataSource2.Update();

DetailsView1.DataBind()
Ann L.
  • 13,760
  • 5
  • 35
  • 66
0

I use a DetailsView in an ongoing project. They are finicky, but they work great when set up correctly.

Several potential issues I can see with your DetailsView are:

Eval vs Bind

As with all databound controls, Databinder.Eval is a read-only databind method. To allow controls to automatically update, you must use Bind in the edit template. Of course, you can manually update your database, but why reinvent the wheel?

<asp:TemplateField HeaderText="Codice Cliente">
<ItemTemplate>
<asp:Label ID="lblCliCod" runat="server" Text='<%# Eval("DataItem.cli_cod") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txtCliCod" runat="server" Text='<%# Bind("DataItem.cli_cod")%>'></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>

Built-in Update functionality vs manual update functionality

You don't really need to use DetailsView1_ItemUpdating unless you are want to catch and modify values after submit and before committing to the datasource. i.e. concatenating individual year/month/day textboxes into a single date.

However, since you are not currently generating an Update button (using property AutoGenerateEditButton="True"), you may need to handle the update manually as you are attempting. Alternatively, for basic binding and update, I would comment out the updating functions, add the autogenerateeditbutton="True" property, and then try updating.

Primary Key

With some datasources, you must specify the DataKeyNames property (your primary key/s of your datasource) on the DetailsView to enable auto-binding. I don't know for sure, but you may also need to set the DefaultMode property.

All properties and methods are explained well on the MSDN DetailsView page, but it's rather verbose. The MSDN Updating a DetailsView page is more concise

MTAdmin
  • 1,023
  • 3
  • 17
  • 36
  • this is really interesting, I've been doing all that eval stuff because that's what I found in an example somwhere, I'm still trying to figure fully how to manage all this stuff, still thanks for the tips – MaddoScientisto Dec 06 '12 at 18:33
  • About the update button, I tried the integrated ones and they actually work, I still can't figure why custom buttons won't though, I recall an MSND article saying that any custom button with CommandName="Edit" would work – MaddoScientisto Dec 06 '12 at 18:46