2011-11-21 15 views
12

Sto sviluppando un Winform e ho bisogno di una checklistbox. Ho i valori memorizzati in un oggetto che ha una proprietà di listino:Come mai checklistbox non ha origine dati? come associare a un elenco di valori?

public static class Fields 
{ 
    public static IList<string> FieldList { get; set; } 

    static Fields() 
    { ...//populate FieldList } 
} 

Ora vorrei il mio CheckedListBox utilizzare Fields.FieldList come origine dati. Dopo la ricerca online ho trovato che avevo bisogno di impostare

//in myForm_Load 
mycheckedListBox.DataSource = Fields.FieldList; 

Ma myCheckedListBox non ha una proprietà DataSource.

Mi manca qualcosa qui?

risposta

14

Per la documentazione, dovrebbe avere questa proprietà ... http://msdn.microsoft.com/en-us/library/system.windows.forms.checkedlistbox.datasource(VS.90).aspx

Tuttavia, ho anche avuto lo stesso problema su un progetto un po 'indietro, e utilizzato this CodeProject article per codificare la soluzione in quello progetto in cui ho bisogno questa caratteristica.

Ricerca di un po 'di più, ho trovato questo:

http://connect.microsoft.com/VisualStudio/feedback/details/115199/checkedlistbox-datasource-displaymember-valuemember-are-hidden

Edit: Il link qui sopra non funziona più, ma l'exceprt sotto è da questo articolo che un tempo vi risiedeva.

Pubblicato da Microsoft il 2005/05/30 alle 10:28
Grazie per il feedback tuttavia questo è di progettazione. Non supportiamo l'associazione dati sul controllo di CheckedListBox . Queste proprietà sono ereditate dalla classe base e non possono essere rimosse, quindi le abbiamo nascoste nella griglia della proprietà e in IntelliSense .

Questo spiega perché la proprietà esiste, ma non viene visualizzata in Intellisense.

Questo post del blog vale la pena di leggere così: http://waxtadpole.wordpress.com/2009/10/12/assigning-custom-class-to-checkedlistbox-datasource/

+1

Grazie. Ho trovato i collegamenti che hai inviato, ma poiché ho visto anche articoli in cui le persone hanno usato questa proprietà, ... Questo è strano ... Grazie comunque, almeno so che qualcun altro ha avuto questo problema. – nche

+0

Ps: non c'è documentazione su come usare l'oggetto. Sono nuovo di Winform Dev (appena iniziato oggi) quindi potresti dirmi come rendere questo articolo disponibile in VS designer? ... – nche

+0

Non penso che tu possa, a meno che tu non dovessi creare la tua classe che sovrascrive la classe CheckBoxList . In progetti più recenti, non ho appena usato il controllo e invece ho usato un DataGridView nei rari casi in cui ho davvero bisogno di essere in grado di controllare gli elementi individualmente. Se DataSource ha un campo di bit, DataGridView lo renderà automaticamente come una colonna di controllo, e in caso contrario, trovo più semplice aggiungere una DataColumn di tipo Boolean per ottenere lo stesso effetto. – David

2

Questo può essere aggirato scorrendo il tuo aspiranti DataSource e aggiungendo i relativi elementi one-at-a-tempo. Per esempio:

Questa, che causerà un'eccezione:

myCheckedListBox.DataSource = myStringList; 

può essere modificato per questo:

foreach (string myString in myStringList) 
{ 
    myCheckedListBox.Items.Add(myString); 
} 
4

Ecco come sto legando un List<T> di User oggetti in CheckedListBox.

((ListBox)myCheckedListBox).DataSource = listOfUsers; 
((ListBox)myCheckedListBox).DisplayMember = "FullName"; 
((ListBox)myCheckedListBox).ValueMember = "UserID"; 

Naturalmente questo non è consigliato, dal momento che la documentazione ci sta dicendo che questa proprietà è nascosta.

Il codice sopra funziona, ma ho notato alcuni effetti collaterali in Visual Studio 2012, quali:

di ritardo per il rendering marcatore controllato:

Dopo aver fatto clic sulla voce desiderata, non v'è fastidioso ritardo per rendere il marcatore "controllato".

Nel mio caso, la proprietà CheckOnClick è True, CausesValidation è False.

+0

Bene, ora mi sto attenendo a 'myCheckedListBox.Items.Add()', dato che la soluzione sopra riportata sta agendo in modo strano. –

1

So che questo è piuttosto vecchio; a beneficio di chiunque abbia ancora lo stesso requisito, ecco cosa ha funzionato per me. Si noti che non ho usato le proprietà DisplayMember o ValueMember, poiché sembra che sia scoraggiata (vedere il post di @David Stratton sopra).

//References 
// https://social.msdn.microsoft.com/Forums/vstudio/en-US/0e0da0c9-299e-46d0-b8b0-4ccdda15894c/how-to-assign-values-to-checkedlistbox-items-and-sum-these-values?forum=csharpgeneral 


using Microsoft.Practices.EnterpriseLibrary.Data; 
using System.Collections.Generic; 
using System.Data; 
using System.Linq; 
using System.Windows.Forms; 

namespace MyApp 
{ 
public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
     DatabaseProviderFactory factory = new DatabaseProviderFactory(); 
     Database db = factory.Create("MyConnString"); 
     DataTable dt = db.ExecuteDataSet(CommandType.StoredProcedure, "ProcGetCustomers").Tables[0]; 
     var custlist = new List<CheckBoxItem<string, string>>(); 
     for (int i = 0; i < dt.Rows.Count; i++) 
     { 
      custlist.Add(Create(dt.Rows[i]["DESC"].ToString(), dt.Rows[i]["CODE"].ToString())); 
     } 
     checkedListBox1.Items.AddRange(custlist.Cast<object>().ToArray()); 


    } 
    public class CheckBoxItem<K, V> 
    { 
     public CheckBoxItem(K displayValue, V hiddenValue) 
     { 
      DisplayValue = displayValue; 
      HiddenValue = hiddenValue; 
     } 

     public K DisplayValue { get; private set; } 
     public V HiddenValue { get; private set; } 


     public override string ToString() 
     { 
      return DisplayValue == null ? "" : DisplayValue.ToString(); 
     } 
    } 
    public static CheckBoxItem<K, V> Create<K, V>(K displayValue, V hiddenValue) 
    { 
     return new CheckBoxItem<K, V>(displayValue, hiddenValue); 
    } 
    } 
} 
2

Personalmente io uso un DataGridView che è destinata a un DataTable che ha un campo booleano insieme a un campo per il valore visualizzato.

Se si nascondono le intestazioni di colonna e le intestazioni di riga, si ottiene qualcosa di molto simile a ciò che offre CheckedListBox.

0

ho risolto il problema modificando il metodo ToString() per il nome che dovrebbe comparire:

public static class Fields 
{ 
    public string MyDisplayMenber{ get; set; } 

    public override string ToString(){ 
     return MyDisplayMenber; 
    } 
} 

e trasformando in lista di array con oggetti:

{ 
    mycheckedlistbox.Items.AddRange(MyList.ToArray<Fields>()); 
} 
Problemi correlati