11 messaggi dal 01 maggio 2004
Ciao ci riprovo... quando aggiorno la gridview gli indici della stessa non sono corretti ad esempio:
ho 5 righe, ricerco 2 righe che si trovano alla 4 e 5 posizione, la gridview mi fa vedere le due righe dopo il databind !! ma l'indice è rimasto sempre lo stesso quindi e.CommandArgument mi ritorna il valore errato (quello della riga 1 o 2).
Ho cercato in vari forum ma non ho trovato niente!
Vi ringrazio Ciao

<qui forse mi sono espresso male>
Ciao,
ho una gridview utenti che mostra gli utenti, in ogni riga c'è un button "reset password". ho inserito una maschera di ricerca che mi seleziona gli utenti in base alla citta o al nome utente, ora finchè la gridview visualizza tutti gli utenti tutto funziona bene, ma quando faccio una ricerca e aggiorno il datasource eseguo il databind la visualizzazione è corretta ma cliccando nel button le righe mantengono i valori precedenti.
Dove sbaglio ?
Ciao e grazie
<>

Gridvew
<div class="DivGridview" style="height: 380px" >
 <asp:SqlDataSource ID="SqlDataSourceUtenti" runat="server" 
        ConnectionString="<%$ ConnectionStrings:MiaConnectionString %>"
           
           SelectCommand="SELECT Utenti.IDutente, Utenti.Utente, Ragionerie.Provincia, Utenti.TipoUtente FROM Utenti INNER JOIN Ragionerie ON Utenti.IDragioneria = Ragionerie.IDragioneria">
    
    </asp:SqlDataSource>
       <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" CssClass="girdView"
           AllowPaging="True" DataSourceID="SqlDataSourceUtenti" PageSize="15" DataKeyNames="IDutente">
           <Columns>
                <asp:BoundField DataField="IdUtente" HeaderText="ID" SortExpression="IDUtente" >
              <ItemStyle Width="30"/> 
              </asp:BoundField>
               <asp:BoundField DataField="Utente" HeaderText="Utente" SortExpression="Utente" >
              <ItemStyle Width="150"/> 
              </asp:BoundField>
               <asp:BoundField DataField="Provincia" HeaderText="Ragioneria" SortExpression="Provincia">
               <ItemStyle Width="180"  HorizontalAlign="Center" /> 
              </asp:BoundField>
               <asp:BoundField DataField="TipoUtente" HeaderText="Ruolo" SortExpression="TipoUtente">
                <ItemStyle Width="100"  /> 
              </asp:BoundField>
              <asp:TemplateField HeaderText="Elimina">  
            <ItemTemplate>  
                <asp:LinkButton   
                    ID="lnkDelete"   
                    runat="server"   
                   
                    Text="Elimina"   
                    OnClick="lnkDelete_Click"
                   
                    OnClientClick="javascript:return confirm('Eliminare Utente selezionato?');">  
                </asp:LinkButton>  
            </ItemTemplate>  
        </asp:TemplateField>  
          <asp:TemplateField HeaderText="Password">
                <ItemTemplate>
                        <asp:Button ID="BtnGWResetPSW" runat="server" Text="Reset Password" OnClick="BtnGWResetPSW_Click"/>
                </ItemTemplate>
                        <ItemStyle HorizontalAlign="Center" Width="40px"></ItemStyle>
            </asp:TemplateField>
           </Columns>
           <HeaderStyle CssClass="tabhead" BorderWidth="1px" ForeColor="#CCFFFF" HorizontalAlign="Center"
               Height="30" />
       </asp:GridView>


Codice ricerca

 Protected Sub Btncerca_Click(sender As Object, e As System.EventArgs) Handles Btncerca.Click
        If Txtcerca.Text <> "" Then
            If DropDownCerca.SelectedValue = 1 Then
                'cerca per utente
                SqlDataSourceUtenti.SelectCommand = "SELECT Utenti.IDutente, Utenti.Utente, Ragionerie.Provincia, Utenti.TipoUtente FROM Utenti INNER JOIN Ragionerie ON Utenti.IDragioneria = Ragionerie.IDragioneria where Utenti.Utente = '" & Txtcerca.Text & "'"
            Else
                'cerca per ragioneria
                SqlDataSourceUtenti.SelectCommand = "SELECT Utenti.IDutente, Utenti.Utente, Ragionerie.Provincia, Utenti.TipoUtente FROM Utenti INNER JOIN Ragionerie ON Utenti.IDragioneria = Ragionerie.IDragioneria where Ragionerie.Provincia = '" & Txtcerca.Text & "'"
            End If

            gridview1.DataBind()

        End If
    End Sub


evento button reset password nella gridview

Protected Sub BtnGWResetPSW_Click(sender As Object, e As System.EventArgs)
        Dim btn As Button = TryCast(sender, Button)

        Dim gvrow As GridViewRow = DirectCast(btn.NamingContainer, GridViewRow)


        Dim IDutente As String = GridView1.DataKeys(gvrow.RowIndex).Values("IDutente").ToString


IDutente ritorna la riga precedente all'aggiornamento della gridview !
Modificato da Giulypop il 15 marzo 2013 17.01 -
Modificato da Giulypop il 15 marzo 2013 17.59 -
Modificato da Giulypop il 15 marzo 2013 18.00 -
11.886 messaggi dal 09 febbraio 2002
Contributi
ciao,
per caso alteri il SelectCommand da qualche altra parte nella pagina? Ad esempio nel Page_Load?
Il punto è questo: dopo aver cliccato il Btncerca che ti restringe l'insieme dei risultati, nessun altra riga di codice dovrebbe modificare il SelectCommand del SqlDataSource.

All'interno di BtnGWResetPSW_Click, gvrow.RowIndex e gvrow.DataItemIndex hanno lo stesso valore?

Un'altra cosa, fai attenzione qui, sei esposto alla Sql Injection. Il problema più comune che può verificarsi è che se l'utente digita un apice dentro Txtcerca, la tua pagina andrà in errore.
... where Utenti.Utente = '" & Txtcerca.Text & "'"
Dovresti usare i SelectParameters del SqlDataSource. Prova a fare tutto in maniera dichiarativa, così non dovrai neanche ripetere le query SQL nel codefile .vb della tua pagina.
Forse con un po' di perizia si riesce a trovare un unico SelectCommand che funzioni nei 3 casi: casella vuota; ricerca su nome utente; ricerca su provincia. Che database usi?

ciao
Modificato da BrightSoul il 17 marzo 2013 01.13 -

Enjoy learning and just keep making
11 messaggi dal 01 maggio 2004
Ciao BrightSoul grazie mille per la risposta, dopo due giorni sono riuscito a capire perchè! Il datasourceID della gridview1 l'avevo dichiarato nella pagina .aspx, quindi ad ogni postback mi caricava la gridview di conseguenza cliccando su BtnGWresetPassword veniva eseguito un nuovo postback ricaricando i valori iniziali e sballando i risuliati.
Ho trovato una soluzione che posto sotto, anche se non mi sembra il massimo, gvrow.RowIndex e gvrow.DataItemIndex, si mi ritornavano lo stesso valore.
Grazie per la dritta di evitare sqlinjection, provero di nuovo a fare tutto in maniera dichiarativa nel file .aspx come da te cosigliato, anche se non saprei come associare l'evento del button "cerca", scusa l'inesperienza.
Per ora ho fatto queste modifiche:

Ho eliminato dalla dichiarazione della gridview il datasourceID e lo carico dal page_load cosi:
    Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        If Session("Ricerca") = "attiva" Then       
            SqlDataSourceUtenti.SelectCommand = Session("sql")
            GridView1.DataSource = SqlDataSourceUtenti
            GridView1.DataBind()
            Session.Clear()
        Else
            GridView1.DataSource = SqlDataSourceUtenti
            GridView1.DataBind()
        End If
    End Sub


nell'evento del button cerca ho modificato cosi:

Protected Sub Btncerca_Click(sender As Object, e As System.EventArgs) Handles Btncerca.Click

        If Txtcerca.Text <> "" Then
          

            If DropDownCerca.SelectedValue = 1 Then
                'cerca per utente
              
                SqlDataSourceUtenti.SelectCommand = "SELECT Utenti.IDutente, Utenti.Utente, Ragionerie.Provincia, Utenti.TipoUtente FROM Utenti INNER JOIN Ragionerie ON Utenti.IDragioneria = Ragionerie.IDragioneria where Utenti.Utente = '" & Txtcerca.Text & "'"

            Else
                'cerca per ragioneria
                SqlDataSourceUtenti.SelectCommand = "SELECT Utenti.IDutente, Utenti.Utente, Ragionerie.Provincia, Utenti.TipoUtente FROM Utenti INNER JOIN Ragionerie ON Utenti.IDragioneria = Ragionerie.IDragioneria where Ragionerie.Provincia = '" & Txtcerca.Text & "'"
            
            End If

            Session("Ricerca") = "attiva"
            Session("sql") = SqlDataSourceUtenti.SelectCommand
            GridView1.DataBind()
        End If
    End Sub


Grazie ancora ciaoo !!!
11 messaggi dal 01 maggio 2004
Per BrightSoul, scusami mi ero dimenticato uso sqlserver 2008 !! Ciao
11.886 messaggi dal 09 febbraio 2002
Contributi
Problema risolto, benissimo :)

Adesso prova ad introdurre dei parametri nel tuo SelectCommand.
Sperimenta su una copia della tua pagina, così non rischi di perdere il progresso che hai raggiunto finora. In più, se questa soluzione dovesse sembrarti inultimente complicata, potrai pur sempre gettar via il duplicato e restare con l'attuale soluzione.

Resta comunque un buon esercizio che ti spinge a pensare a come puoi usare il codice T-SQL per lasciar svolgere alcuni compiti a SQL Server, anziché doverlo fare da vb.net.

Parti da un caso facile: facciamo finta che Utenti.Utente sia l'unico campo su cui tu debba cercare. Al SelectCommand dunque accoda una clausola WHERE del tipo Utenti.Utente=@txtcerca. Ecco come diventerebbe il SqlDataSource:
<asp:SqlDataSource ID="SqlDataSourceUtenti" runat="server" ConnectionString="<%$ ConnectionStrings:MiaConnectionString %>"
  SelectCommand="SELECT Utenti.IDutente, Utenti.Utente, Ragionerie.Provincia, Utenti.TipoUtente FROM Utenti INNER JOIN Ragionerie ON Utenti.IDragioneria = Ragionerie.IDragioneria WHERE Utenti.Utente=@txtcerca">

<SelectParameters>
    <asp:ControlParameter ControlID="Txtcerca" PropertyName="Text" Name="txtcerca"  />
</SelectParameters>

</asp:SqlDataSource>
Ho dovuto aggiungere anche un ControlParameter, così che il segnaposto @txtcerca che ho usato nella query venga poi sostituito dalla proprietà Text di Txtcerca.
Avendo reso la query parametrica, non bisogna più preoccuparsi di SQL Injection perché eventuali combinazioni "malevole" di caratteri verranno rese innocue.

Giulypop ha scritto:

non saprei come associare l'evento del button "cerca"

Non associarlo, anzi, elimina del tutto la funzione Btncerca_Click. Il nostro scopo è fare tutto in maniera dichiarativa quindi il codice che avevi messo all'interno di quella funzione andremo presto a "convertirlo" in codice SQL. Fai in modo che Btncerca sia un semplice asp:Button, il cui evento click non è gestito. Questo bottone deve solo servire a causare il postback della pagina dopo che l'utente ha digitato qualcosa in Txtcerca, in modo che il set di risultati possa essere rigenerato.

Quindi lancia la pagina, digita il nome di un utente nella textbox, clicca il bottone e vedrai apparire le sue righe nella GridView.

Adesso però già sorge un problema. La WHERE Utenti.Utente=@txtcerca non mi consentirà mai di visualizzare tutti i risultati. Invece magari voglio che se l'utente non digita nulla, non avvenga alcun filtraggio.

Allora possiamo alterare leggermente la WHERE per fare in modo che questo caso sia gestito:
WHERE Utenti.Utente=COALESCE(@txtcerca, Utenti.Utente)

e al ControlParameter aggiungere l'attributo ConvertEmptyStringToNull="true"

Quello che succederà è questo: se l'utente non digita nulla, alla query verrà passato un valore null per il parametro @txtcerca. La funzione COALESCE restituirà il primo parametro (@txtcerca) purché non sia null ma, dato che lo è, allora restituirà il secondo (Utenti.Utente).
Quindi, nel caso in cui non si digiti alcun testo, il valore di Utenti.Utente verrebbe confrontato con sé stesso e ciò produrrebbe una condizione sempre verificata per ogni record. In sintesi: se non si digita nulla, i risultati appariranno tutti.

Ora hai un'ultima complicazione: fare in modo che la sola textbox Txtcerca possa cercare su più campi, in base al valore della DropDownList.
Nel consegue che il primo membro dell'uguaglianza (WHERE Utenti.Utente=) deve variare in base al valore DropDownCerca. Per questo puoi usare un'istruzione CASE e introdurre un secondo parametro per DropDownCerca.
WHERE (CASE @dropdowncerca WHEN '1' THEN Utenti.Utente ELSE Ragionerie.Provincia END)=...
Quando il parametro @dropdowncerca avrà il valore di '1', allora il campo che entra in gioco nell'uguaglianza sarà Utenti.Utente, altrimenti sarà Ragionerie.Provincia.
Questo richiede che sia presente anche il secondo ControlParameter.
<asp:ControlParameter ControlID="DropDownCerca" PropertyName="SelectedValue" Name="dropdowncerca"  />


Sembra complicato fin qui? Decidi tu se vale la pena di usare questo sistema per evitare ripetizioni di codice SQL nel codefile.

Certamente il SelectCommand diventa un po' meno leggibile per via delle istruzioni COALESCE e CASE che sono state introdotte. Ancor più perché il campo su cui cercare è menzionato in entrambi i membri dell'uguaglianza. Se prima avevi:
Utenti.Utente=COALESCE(@txtcerca, Utenti.Utente)
Ora dovrai fare:
WHERE (CASE @dropdowncerca WHEN '1' THEN Utenti.Utente ELSE Ragionerie.Provincia END) = COALESCE(@txtcerca, (CASE @dropdowncerca WHEN '1' THEN Utenti.Utente ELSE Ragionerie.Provincia END))
yikes! Ma per fortuna in Sql Server puoi usare una Common Table Expression per restituire leggibilità alla query ed evitare ripetizioni. Ecco l'esempio completo.
<asp:SqlDataSource ID="SqlDataSourceUtenti" runat="server" CancelSelectOnNullParameter="false"
         SelectCommand="WITH MiaTab AS( SELECT Utenti.IDutente, Utenti.Utente, Ragionerie.Provincia, Utenti.TipoUtente, (CASE @dropdowncerca WHEN '1' THEN Utenti.Utente ELSE Ragionerie.Provincia END) as CampoRicerca FROM Utenti INNER JOIN Ragionerie ON Utenti.IDragioneria = Ragionerie.IDragioneria) SELECT * FROM MiaTab WHERE CampoRicerca=COALESCE(@txtcerca, CampoRicerca)"
         ConnectionString="<%$ ConnectionStrings:MiaConnectionString %>">

<SelectParameters>
    <asp:ControlParameter ControlID="Txtcerca" PropertyName="Text" Name="txtcerca" ConvertEmptyStringToNull="true"  />
    <asp:ControlParameter ControlID="DropDownCerca" PropertyName="SelectedValue" Name="dropdowncerca" ConvertEmptyStringToNull="true"  />
</SelectParameters>
        
</asp:SqlDataSource>


ciao
Modificato da BrightSoul il 18 marzo 2013 22.30 -

Enjoy learning and just keep making
11 messaggi dal 01 maggio 2004
Grazie mille BrightSoul !!
Non ci sarei mai arrivato, ora sono al lavoro, ma questa sera provo sicuramente poi ti faccio sapere, di sicuro è una soluzione molto ma molto migliore della mia.
Grazie ancora ciao!!



BrightSoul ha scritto:
Problema risolto, benissimo :)

Adesso prova ad introdurre dei parametri nel tuo SelectCommand.
Sperimenta su una copia della tua pagina, così non rischi di perdere il progresso che hai raggiunto finora. In più, se questa soluzione dovesse sembrarti inultimente complicata, potrai pur sempre gettar via il duplicato e restare con l'attuale soluzione.

Resta comunque un buon esercizio che ti spinge a pensare a come puoi usare il codice T-SQL per lasciar svolgere alcuni compiti a SQL Server, anziché doverlo fare da vb.net.

Parti da un caso facile: facciamo finta che Utenti.Utente sia l'unico campo su cui tu debba cercare. Al SelectCommand dunque accoda una clausola WHERE del tipo Utenti.Utente=@txtcerca. Ecco come diventerebbe il SqlDataSource:
<asp:SqlDataSource ID="SqlDataSourceUtenti" runat="server" ConnectionString="<%$ ConnectionStrings:MiaConnectionString %>"
  SelectCommand="SELECT Utenti.IDutente, Utenti.Utente, Ragionerie.Provincia, Utenti.TipoUtente FROM Utenti INNER JOIN Ragionerie ON Utenti.IDragioneria = Ragionerie.IDragioneria WHERE Utenti.Utente=@txtcerca">

<SelectParameters>
    <asp:ControlParameter ControlID="Txtcerca" PropertyName="Text" Name="txtcerca"  />
</SelectParameters>

</asp:SqlDataSource>
Ho dovuto aggiungere anche un ControlParameter, così che il segnaposto @txtcerca che ho usato nella query venga poi sostituito dalla proprietà Text di Txtcerca.
Avendo reso la query parametrica, non bisogna più preoccuparsi di SQL Injection perché eventuali combinazioni "malevole" di caratteri verranno rese innocue.

Giulypop ha scritto:

non saprei come associare l'evento del button "cerca"

Non associarlo, anzi, elimina del tutto la funzione Btncerca_Click. Il nostro scopo è fare tutto in maniera dichiarativa quindi il codice che avevi messo all'interno di quella funzione andremo presto a "convertirlo" in codice SQL. Fai in modo che Btncerca sia un semplice asp:Button, il cui evento click non è gestito. Questo bottone deve solo servire a causare il postback della pagina dopo che l'utente ha digitato qualcosa in Txtcerca, in modo che il set di risultati possa essere rigenerato.

Quindi lancia la pagina, digita il nome di un utente nella textbox, clicca il bottone e vedrai apparire le sue righe nella GridView.

Adesso però già sorge un problema. La WHERE Utenti.Utente=@txtcerca non mi consentirà mai di visualizzare tutti i risultati. Invece magari voglio che se l'utente non digita nulla, non avvenga alcun filtraggio.

Allora possiamo alterare leggermente la WHERE per fare in modo che questo caso sia gestito:
WHERE Utenti.Utente=COALESCE(@txtcerca, Utenti.Utente)

e al ControlParameter aggiungere l'attributo ConvertEmptyStringToNull="true"

Quello che succederà è questo: se l'utente non digita nulla, alla query verrà passato un valore null per il parametro @txtcerca. La funzione COALESCE restituirà il primo parametro (@txtcerca) purché non sia null ma, dato che lo è, allora restituirà il secondo (Utenti.Utente).
Quindi, nel caso in cui non si digiti alcun testo, il valore di Utenti.Utente verrebbe confrontato con sé stesso e ciò produrrebbe una condizione sempre verificata per ogni record. In sintesi: se non si digita nulla, i risultati appariranno tutti.

Ora hai un'ultima complicazione: fare in modo che la sola textbox Txtcerca possa cercare su più campi, in base al valore della DropDownList.
Nel consegue che il primo membro dell'uguaglianza (WHERE Utenti.Utente=) deve variare in base al valore DropDownCerca. Per questo puoi usare un'istruzione CASE e introdurre un secondo parametro per DropDownCerca.
WHERE (CASE @dropdowncerca WHEN '1' THEN Utenti.Utente ELSE Ragionerie.Provincia END)=...
Quando il parametro @dropdowncerca avrà il valore di '1', allora il campo che entra in gioco nell'uguaglianza sarà Utenti.Utente, altrimenti sarà Ragionerie.Provincia.
Questo richiede che sia presente anche il secondo ControlParameter.
<asp:ControlParameter ControlID="DropDownCerca" PropertyName="SelectedValue" Name="dropdowncerca"  />


Sembra complicato fin qui? Decidi tu se vale la pena di usare questo sistema per evitare ripetizioni di codice SQL nel codefile.

Certamente il SelectCommand diventa un po' meno leggibile per via delle istruzioni COALESCE e CASE che sono state introdotte. Ancor più perché il campo su cui cercare è menzionato in entrambi i membri dell'uguaglianza. Se prima avevi:
Utenti.Utente=COALESCE(@txtcerca, Utenti.Utente)
Ora dovrai fare:
WHERE (CASE @dropdowncerca WHEN '1' THEN Utenti.Utente ELSE Ragionerie.Provincia END) = COALESCE(@txtcerca, (CASE @dropdowncerca WHEN '1' THEN Utenti.Utente ELSE Ragionerie.Provincia END))
yikes! Ma per fortuna in Sql Server puoi usare una Common Table Expression per restituire leggibilità alla query ed evitare ripetizioni. Ecco l'esempio completo.
<asp:SqlDataSource ID="SqlDataSourceUtenti" runat="server" CancelSelectOnNullParameter="false"
         SelectCommand="WITH MiaTab AS( SELECT Utenti.IDutente, Utenti.Utente, Ragionerie.Provincia, Utenti.TipoUtente, (CASE @dropdowncerca WHEN '1' THEN Utenti.Utente ELSE Ragionerie.Provincia END) as CampoRicerca FROM Utenti INNER JOIN Ragionerie ON Utenti.IDragioneria = Ragionerie.IDragioneria) SELECT * FROM MiaTab WHERE CampoRicerca=COALESCE(@txtcerca, CampoRicerca)"
         ConnectionString="<%$ ConnectionStrings:MiaConnectionString %>">

<SelectParameters>
    <asp:ControlParameter ControlID="Txtcerca" PropertyName="Text" Name="txtcerca" ConvertEmptyStringToNull="true"  />
    <asp:ControlParameter ControlID="DropDownCerca" PropertyName="SelectedValue" Name="dropdowncerca" ConvertEmptyStringToNull="true"  />
</SelectParameters>
        
</asp:SqlDataSource>


ciao
Modificato da BrightSoul il 18 marzo 2013 22.30 -
11 messaggi dal 01 maggio 2004
Grazieee funziona benissimo ho anche tolto tutto l'ambaradan che avevo messo nel code behaind !
Grazie anche per la tua chiarezza nello spiegamento.

Ciaooo Giuliano


Giulypop ha scritto:
Grazie mille BrightSoul !!
Non ci sarei mai arrivato, ora sono al lavoro, ma questa sera provo sicuramente poi ti faccio sapere, di sicuro è una soluzione molto ma molto migliore della mia.
Grazie ancora ciao!!



BrightSoul ha scritto:
Problema risolto, benissimo :)

Adesso prova ad introdurre dei parametri nel tuo SelectCommand.
Sperimenta su una copia della tua pagina, così non rischi di perdere il progresso che hai raggiunto finora. In più, se questa soluzione dovesse sembrarti inultimente complicata, potrai pur sempre gettar via il duplicato e restare con l'attuale soluzione.

Resta comunque un buon esercizio che ti spinge a pensare a come puoi usare il codice T-SQL per lasciar svolgere alcuni compiti a SQL Server, anziché doverlo fare da vb.net.

Parti da un caso facile: facciamo finta che Utenti.Utente sia l'unico campo su cui tu debba cercare. Al SelectCommand dunque accoda una clausola WHERE del tipo Utenti.Utente=@txtcerca. Ecco come diventerebbe il SqlDataSource:
<asp:SqlDataSource ID="SqlDataSourceUtenti" runat="server" ConnectionString="<%$ ConnectionStrings:MiaConnectionString %>"
  SelectCommand="SELECT Utenti.IDutente, Utenti.Utente, Ragionerie.Provincia, Utenti.TipoUtente FROM Utenti INNER JOIN Ragionerie ON Utenti.IDragioneria = Ragionerie.IDragioneria WHERE Utenti.Utente=@txtcerca">

<SelectParameters>
    <asp:ControlParameter ControlID="Txtcerca" PropertyName="Text" Name="txtcerca"  />
</SelectParameters>

</asp:SqlDataSource>
Ho dovuto aggiungere anche un ControlParameter, così che il segnaposto @txtcerca che ho usato nella query venga poi sostituito dalla proprietà Text di Txtcerca.
Avendo reso la query parametrica, non bisogna più preoccuparsi di SQL Injection perché eventuali combinazioni "malevole" di caratteri verranno rese innocue.

Giulypop ha scritto:

non saprei come associare l'evento del button "cerca"

Non associarlo, anzi, elimina del tutto la funzione Btncerca_Click. Il nostro scopo è fare tutto in maniera dichiarativa quindi il codice che avevi messo all'interno di quella funzione andremo presto a "convertirlo" in codice SQL. Fai in modo che Btncerca sia un semplice asp:Button, il cui evento click non è gestito. Questo bottone deve solo servire a causare il postback della pagina dopo che l'utente ha digitato qualcosa in Txtcerca, in modo che il set di risultati possa essere rigenerato.

Quindi lancia la pagina, digita il nome di un utente nella textbox, clicca il bottone e vedrai apparire le sue righe nella GridView.

Adesso però già sorge un problema. La WHERE Utenti.Utente=@txtcerca non mi consentirà mai di visualizzare tutti i risultati. Invece magari voglio che se l'utente non digita nulla, non avvenga alcun filtraggio.

Allora possiamo alterare leggermente la WHERE per fare in modo che questo caso sia gestito:
WHERE Utenti.Utente=COALESCE(@txtcerca, Utenti.Utente)

e al ControlParameter aggiungere l'attributo ConvertEmptyStringToNull="true"

Quello che succederà è questo: se l'utente non digita nulla, alla query verrà passato un valore null per il parametro @txtcerca. La funzione COALESCE restituirà il primo parametro (@txtcerca) purché non sia null ma, dato che lo è, allora restituirà il secondo (Utenti.Utente).
Quindi, nel caso in cui non si digiti alcun testo, il valore di Utenti.Utente verrebbe confrontato con sé stesso e ciò produrrebbe una condizione sempre verificata per ogni record. In sintesi: se non si digita nulla, i risultati appariranno tutti.

Ora hai un'ultima complicazione: fare in modo che la sola textbox Txtcerca possa cercare su più campi, in base al valore della DropDownList.
Nel consegue che il primo membro dell'uguaglianza (WHERE Utenti.Utente=) deve variare in base al valore DropDownCerca. Per questo puoi usare un'istruzione CASE e introdurre un secondo parametro per DropDownCerca.
WHERE (CASE @dropdowncerca WHEN '1' THEN Utenti.Utente ELSE Ragionerie.Provincia END)=...
Quando il parametro @dropdowncerca avrà il valore di '1', allora il campo che entra in gioco nell'uguaglianza sarà Utenti.Utente, altrimenti sarà Ragionerie.Provincia.
Questo richiede che sia presente anche il secondo ControlParameter.
<asp:ControlParameter ControlID="DropDownCerca" PropertyName="SelectedValue" Name="dropdowncerca"  />


Sembra complicato fin qui? Decidi tu se vale la pena di usare questo sistema per evitare ripetizioni di codice SQL nel codefile.

Certamente il SelectCommand diventa un po' meno leggibile per via delle istruzioni COALESCE e CASE che sono state introdotte. Ancor più perché il campo su cui cercare è menzionato in entrambi i membri dell'uguaglianza. Se prima avevi:
Utenti.Utente=COALESCE(@txtcerca, Utenti.Utente)
Ora dovrai fare:
WHERE (CASE @dropdowncerca WHEN '1' THEN Utenti.Utente ELSE Ragionerie.Provincia END) = COALESCE(@txtcerca, (CASE @dropdowncerca WHEN '1' THEN Utenti.Utente ELSE Ragionerie.Provincia END))
yikes! Ma per fortuna in Sql Server puoi usare una Common Table Expression per restituire leggibilità alla query ed evitare ripetizioni. Ecco l'esempio completo.
<asp:SqlDataSource ID="SqlDataSourceUtenti" runat="server" CancelSelectOnNullParameter="false"
         SelectCommand="WITH MiaTab AS( SELECT Utenti.IDutente, Utenti.Utente, Ragionerie.Provincia, Utenti.TipoUtente, (CASE @dropdowncerca WHEN '1' THEN Utenti.Utente ELSE Ragionerie.Provincia END) as CampoRicerca FROM Utenti INNER JOIN Ragionerie ON Utenti.IDragioneria = Ragionerie.IDragioneria) SELECT * FROM MiaTab WHERE CampoRicerca=COALESCE(@txtcerca, CampoRicerca)"
         ConnectionString="<%$ ConnectionStrings:MiaConnectionString %>">

<SelectParameters>
    <asp:ControlParameter ControlID="Txtcerca" PropertyName="Text" Name="txtcerca" ConvertEmptyStringToNull="true"  />
    <asp:ControlParameter ControlID="DropDownCerca" PropertyName="SelectedValue" Name="dropdowncerca" ConvertEmptyStringToNull="true"  />
</SelectParameters>
        
</asp:SqlDataSource>


ciao
Modificato da BrightSoul il 18 marzo 2013 22.30 -

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.