2010-03-26 3 views
0

J'essaye d'écrire une méthode, qui prend un ComboBox, un DataTable et un TextBox comme arguments. Le but de cela est de filtrer les membres affichés dans le ComboBox en fonction du TextBox.Text. Le DataTable contient la liste complète des entrées possibles qui seront ensuite filtrées. Pour le filtrage, je crée un DataView du DataTable, ajoute un RowFilter, puis lier cette View au ComboBox en tant que DataSource.Utiliser la ligne vide par défaut dans un ComboBox avec le style "DropDownList"?

Pour empêcher l'utilisateur de taper dans le ComboBox, je choisis le DropDownStyle DropDownList. Cela fonctionne bien jusqu'à présent, sauf que l'utilisateur doit également être en mesure de ne rien choisir/ligne vide. En fait, cela devrait être le membre par défaut à afficher (pour éviter de choisir un mauvais membre par accident, si l'utilisateur clique trop vite sur la boîte de dialogue).

J'ai essayé de résoudre ce problème en ajoutant une nouvelle ligne à la vue. Bien que cela fonctionne dans certains cas, le problème principal ici est que n'importe quel DataTable peut être passé à la méthode. Si le DataTable contient des colonnes qui ne peuvent pas être nulles et ne contiennent pas de valeur par défaut, je suppose que je vais déclencher une erreur en ajoutant une ligne vide.

Une possibilité consiste à créer une vue qui contient uniquement la colonne définie comme DisplayMember et celle définie comme ValueMember. Hélas, cela ne peut pas être fait avec une vue en C#. Je voudrais éviter de créer une vraie copie du DataTable à tout prix, car qui sait à quel point ça va arriver avec le temps.

Avez-vous des suggestions pour contourner ce problème?

Au lieu d'une vue, est-ce que je pourrais créer un objet contenant deux membres et assigner le DisplayMember et le ValueMember à ces membres? Les membres seraient-ils adoptés en tant que référence (ce que j'espère) ou serait-il copié (si tel n'était pas le cas)?

Merci beaucoup pour votre aide!

Meilleures salutations

public static void ComboFilter(ComboBox cb, DataTable dtSource, TextBox filterTextBox) 
{ 
cb.DropDownStyle = ComboBoxStyle.DropDownList; 
string displayMember = cb.DisplayMember; 
DataView filterView = new DataView(dtSource); 
filterView.AddNew(); 
filterView.RowFilter = displayMember + " LIKE '%" + filterTextBox.Text + "%'"; 
cb.DataSource = filterView; 
} 
+0

P.S. Désolé, le code est en quelque sorte vissé :( –

+0

Pour le formatage du code, sélectionnez votre code et donnez Ctrl + K – Amsakanna

+0

réservoirs pour l'indice! Mais je ne peux pas éditer/corriger ma question, puis-je? –

Répondre

0

Ok, par hasard, je suis tombé sur une solution de travail: Toute modification apportée à un DataView - comme l'ajout d'une nouvelle ligne - sont censés être terminés à l'aide .EndEdit. Si vous ne le faites pas, vous serez confronté à des effets secondaires, tels que la ligne ajoutée n'étant pas correctement triée. MAIS: en ne ajoutant pas .EndEdit, vous aurez aussi un avantage: C# ne vérifie pas, si l'une des colonnes du DataTable sous-jacent (dtSource) n'autorise pas null! Donc, en tant que solution, j'ai ajouté .EndEdit à un try-Block. Si le DataTable autorise null pour chaque colonne, cela fonctionnera et la ligne vide apparaîtra au-dessus de la liste déroulante. Si elle n'autorise null, EndEdit ne sera pas exécuté, la ligne vide sera quand même ajoutée, en bas de la ComboBox.

Veuillez noter que si vous avez défini l'auto-incrémentation dans dtSource, la ligne vide renvoie également une valeur SelectedValue (très probablement -1). Cela doit être pris en compte lors de l'utilisation de cette méthode!

À la votre!

public static void ComboFilter(ComboBox cb, DataTable dtSource, TextBox filterTextBox) 
{ 
    cb.DropDownStyle = ComboBoxStyle.DropDownList; 
    string displayMember = cb.DisplayMember; 
    DataView filterView = new DataView(dtSource); 
    DataRowView newRow = filterView.AddNew(); 
    newRow[displayMember] = ""; 
    try { newRow.EndEdit(); } // fails, if a column in dtSource does not allow null 
    catch (Exception) { }  // works, but the empty line will appear at the end 
    filterView.RowFilter = displayMember + " LIKE '%" + filterTextBox.Text + "%'"; 
    filterView.Sort = displayMember; 
    cb.DataSource = filterView; 
} 
Questions connexes