ComboBox & Prima elemento "vuoto"

sabato 16 luglio 2005 - 11.43

astroman Profilo | Junior Member

Ho dei problemi a capire come inserire una prima riga di un combobox vuota dopo aver fatto il databing su un Windows Form.Il codice è il seguente e funziona alla perfezione..

DataTable dt= new DataTable();
dt.Clear();
OleDbConnection cn=new OleDbConnection(<connessione>);
cn.Open();

OleDbDataAdapter da = new OleDbDataAdapter("SELECT id,campionato FROM Master_Campionati WHERE Id_Stagione=" + Season.SeasonSelected.ToString() + " ORDER BY Campionato",cn);
da.Fill(dt);

cbo.DisplayMember = "campionato";
cbo.ValueMember = "id";
cbo.DataSource = dt;
cbo.SelectedIndex=-1;

da.Dispose();
cn.Close();

Ora la mia domanda è: voglio che alla prima riga ci sia o un campo vuoto o una scritta tipo "seleziona un elemento" ma quando cerco di fare un cbo.items.insert mi da un errore dicendo che dopo aver settato il datasource non posso aggiungere elementi al combo!!!
Ho bisogno urgentissimo di questa informazione.

Cteniza Profilo | Guru

Ti crei una tabella "volante", il cui codice principale è un numero di riga progressivo, ci aggiungi i campi che ti servono per il binding.
Poi crei la riga vuota (che deve comparire per prima) e aggiungi le righe provenienti dall'altra tabella.
Poi bindi questa tabella con la combobox.
Quando devi aggiungere / togliere righe aggiorni la tabella.
Quando devi aggiornare il database estrai le righe con variazioni rifai le operazioni sulla tabella ufficiale.


astroman Profilo | Junior Member

>Ti crei una tabella "volante", il cui codice principale è un
>numero di riga progressivo, ci aggiungi i campi che ti servono
>per il binding.
>Poi crei la riga vuota (che deve comparire per prima) e aggiungi
>le righe provenienti dall'altra tabella.
>Poi bindi questa tabella con la combobox.
>Quando devi aggiungere / togliere righe aggiorni la tabella.
>Quando devi aggiornare il database estrai le righe con variazioni
>rifai le operazioni sulla tabella ufficiale.
>

Tabella...volante?!?
Partendo dall'esempio che ho fatto io...come faresti?
>
>

Cteniza Profilo | Guru

>Tabella...volante?!?
>Partendo dall'esempio che ho fatto io...come faresti?

Dim k As Integer
Dim campo() As String = {"Chiave","ID","Campionato"}
Dim s() As String = {"System.Int32","System.Int32","System.String"}
Dim tb As New DataTable("Tabella1")
Dim keyColumn(0) As DataColumn
For k = 0 To campo.Length - 1
Dim cl As New DataColumn
cl.ColumnName = campo(k)
cl.DataType = Type.GetType(s(k))
tb.Columns.Add(cl)
If k = 0 Then
keyColumn(0) = cl
End If
Next
tb.PrimaryKey = keyColumn
For k = -1 To dt.Rows.Count - 1
Dim dr As DataRow = tb.NewRow()
dr("Chiave") = k
dr("ID") = 0
dr("Campionato") = ""
If (k <> -1) Then
dr("Id") = tb.Rows(k)("Id")
dr("Campionato") = tb.Rows(k)("Campionato")
End If
tb.Rows.Add(dr)
Next
Poi fai il binding con la nuova tabella



astroman Profilo | Junior Member

Ah!...cavolo...
ma non c'è un modo un pò più "pratico"?
A parte che è Vb.Net...e ci capisco poco.. :D


Cteniza Profilo | Guru

>Ah!...cavolo...
>ma non c'è un modo un pò più "pratico"?
>A parte che è Vb.Net...e ci capisco poco.. :D

Non esiste un metodo più pratico.
Detto fra noi se ti perdi con queste cose siamo messi un tantino male!
int k;
string[] campo = {"Chiave", "ID", "Campionato"};
string[] s = {"System.Int32", "System.Int32", "System.String"};
DataTable tb = new DataTable("Tabella1");
DataColumn[] keyColumn = new DataColumn[1];
for (int k = 0; k <= campo.Length - 1; k++) {
DataColumn cl = new DataColumn();
cl.ColumnName = campo[k];
cl.DataType = Type.GetType(s[k]);
tb.Columns.Add(cl);
if (k == 0) {
keyColumn[0] = cl;
}
}
tb.PrimaryKey = keyColumn;
for (int k = -1; k <= dt.Rows.Count - 1; k++) {
DataRow dr = tb.NewRow();
dr["Chiave"] = k;
dr["ID"] = 0;
dr["Campionato"] = "";
if ((k != -1)) {
dr["Id"] = tb.Rows[k]["Id"];
dr["Campionato"] = tb.Rows[k]["Campionato"];
}
tb.Rows.Add(dr);
}
}



astroman Profilo | Junior Member

Eh sai dopo 8 anni di sola programmazione web andare a programmare su Windows Form non è che sia così "immediato" dopo neanche un mese che ci lavoro sopra...
Cmq ti ringrazio molto per l'aiuto

astroman Profilo | Junior Member

Anche se giustamente come dici non ci sò tanto fare ( è vero eh?:D), ho trovato una soluzione molto comoda per fare la stessa cosa ma più velocemente.
Che ne pensi?

cn = new OleDbConnection(gu.actualConn);
cn.Open();
da = new OleDbDataAdapter();
ds = new DataSet();
cmd = new OleDbCommand("SELECT id,campionato FROM Master_Campionati WHERE Id_Stagione=" + Season.SeasonSelected.ToString() + " ORDER BY Campionato",cn);
da.SelectCommand = cmd;
da.Fill(ds, "C");
DataTable dtC= ds.Tables["C"];
DataRow row = dtC.NewRow();
row[0] = 0;
row[1] = " ";
dtC.Rows.InsertAt(row, 0);

comboBox1.DataSource = dtC;
comboBox1.ValueMember = "id";
comboBox1.DisplayMember = "campionato";

A mio avviso è anche più performante prestazionalmente...ma aspetto un giudizio più esperto!:D

Cteniza Profilo | Guru

Nulla da dire, il problema è che se devi poi gestire il collegamento con la base e riportare le righe aggiornate come fai se hai delle righe che non vuoi trasmettere?


Cteniza Profilo | Guru

Un altro problema è dato dalla chiave primaria della tabella "originale", facendo un'altra tabella con un nuovo campo chiave puoi gestirla in modo autonomo, utilizzando la chiave della tabella originale potresti avere dei problemi di chiavi duplicate.
Comunque se quello che hai mostrato è tutto (non fai gli aggiornamenti) il tuo metodo è senz'altro più veloce.


astroman Profilo | Junior Member

Si, in effetti inizialmente mi son spiegato male..quello che dovevo fare, pratica, era prendere i dati da una tabella del db, riempire il combo e alla selezione di un elemento di quest'ultimo vado a cambiare i dati visualizzati in una sottostante listbox.
In ogni caso, in futuro logicamente mi capiterà una situazione che giustamente hai posto te, cioè che dovrei aggiornare anche il combo: ma se in questo caso, ogni volta che chiamo il metodo per il binding dei dati al combo distruggo e ricreo il dataset, non otterrei lo stesso risultato?O ho capito male quello che intendevi?

LudovicoVan Profilo | Junior Member

Scusate,

mai pensato che si può fare direttamente dall'SQL con una UNION?

La sintassi è più o meno (dipende dal db):
--------------------------------------------------------------
SELECT -1 AS id, "-- Scegli" AS campionato, -1 AS orderidx
UNION
SELECT id, campionato, 0 AS orderidx FROM Master_Campionati
WHERE Id_Stagione = " + Season.SeasonSelected.ToString() + "
ORDER BY orderidx, campionato
--------------------------------------------------------------

Ciao. -LV


Cteniza Profilo | Guru

Si è una soluzione ma il problema posto inizialmente era (se ho capito bene altrimenti mi scuso in anticipo):

Ho una combobox in cui ci voglio caricare dei dati in parte provenienti dal database ed in parte aggiunti a piacere.
Se bindo la tabella alla combo poi non mi consente di aggiungere delle righe direttamente.

Allora ho proposto di creare un'altra tabella da "smanazzare" a piacere mettendovi sia le righe aggiunte che le righe provenienti dal database.
Così si può bindare alla combo e utilizzare i meccanismi naturali per agire sulle righe, si possono togliere, aggiungere, rinumerare, mantenendo comunque sempre il collegamento con la tabella originale per poter eventualmente riversare indietro (a piacere) gli aggiornamenti (anche nessuno!)



astroman Profilo | Junior Member

Ah no no, non era da fare una soluzione così complicata!:D
A me interessava, al momento, inserire i dati direttamente per consultazione da un DB, sola lettura..e aggiungergi il primo campo bianco, tutto quà.
Effettivamente la soluzione che hai proposto te, vista nell'ottica aggiornamento record disconnessi è ottima!:D

Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5