[C#] listbox update datasource niet

Pagina: 1
Acties:

  • brammetje
  • Registratie: Oktober 2000
  • Laatst online: 12-01-2025
ik assign een datasource als volgt:
code:
1
2
3
4
5
fieldsContainer = new FieldsContainer();
fieldsContainer.Add( new Field("Foo", "Bar", "Text") );
this.FieldList.DisplayMember  = "Description";
this.FieldList.ValueMember    = "Name";
this.FieldList.DataSource     = this.fieldsContainer;

dit werkt prima.
Ook als ik hierna de datasource verander update hij de lisbox :
code:
1
2
3
4
5
6
7
fieldsContainer = new FieldsContainer();
fieldsContainer.Add( new Field("Foo", "Bar", "Text") );
this.FieldList.DisplayMember  = "Description";
this.FieldList.ValueMember    = "Name";
this.FieldList.DataSource     = this.fieldsContainer;

fieldsContainer.Add( new Field("Bar", "Foo", "Text") );

werkt ook..

Maar als ik in een andere functie iets add in mijn fieldsContainer dan update hij de fieldList niet.

Een oplossing daarvoor was een event af te vuren vanuit de fieldcontainer wanneer deze gewijzigd wordt. Dit event vang ik op en plak er deze code aan:
code:
1
2
3
4
this.FieldList.DataSource     = null;
this.FieldList.DisplayMember  = "Description";
this.FieldList.ValueMember    = "Name";
this.FieldList.DataSource     = this.fieldsContainer;


Het werkt wel, maar lijkt met niet de bedoeling. Ik heb al heel wat lopen zoeken in msdn maar kan geen oplossing vinden, weet iemand anders dit misschien??

[ Voor 0% gewijzigd door brammetje op 17-09-2002 02:22 . Reden: assing ]


  • mulder
  • Registratie: Augustus 2001
  • Laatst online: 31-08 15:46

mulder

ik spuug op het trottoir

DataBind?

oogjes open, snaveltjes dicht


  • brammetje
  • Registratie: Oktober 2000
  • Laatst online: 12-01-2025
Het is geen asp.net-pagina maar een gewone windows app. DataBind kent hij (dus) niet. Fieldscontainer is trouwens een arraylist.

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Als ik het zo nu bekijk, lijkt het mij erg merkwaardig dat het wel werkt in de methode zelf, maar niet in een andere methode. Zo'n verschil duidt toch waarschijnlijk op een implementatie-fout van jouw kant en niet een intern probleem.

Het eerste waar ik aan zou denken is dat het per ongeluk niet dezelfde FieldsContainer is waar je daar de de data aan toevoegd? Dit zou misschien ook verklaren waardoor het wel werkt als je keihard de datasource weer aanpast.

(dit staat ook op Javahova).

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • brammetje
  • Registratie: Oktober 2000
  • Laatst online: 12-01-2025
ok, mijn (relevante) code dan:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private FieldsContainer fieldsContainer;
public Form1()
{
    InitializeComponent();
    this.fieldsContainer = new FieldsContainer();
            
    this.listBox1.DisplayMember = "Description";
    this.listBox1.ValueMember = "Name";
    this.listBox1.DataSource = this.fieldsContainer;

    this.fieldsContainer.Add( new Field("test", "blaat", "Text") );
}

private void button1_Click(object sender, System.EventArgs e) {
    this.fieldsContainer.Add( new Field("test", "blaat", "Text") );
}


bij het constructen voegt hij wel het veld toe, maar bij de button-click niet. :'(

voor de volledigheid ook nog even de code van mijn fieldsContainer:
C#:
1
2
niet meer nodig, ik heb het met een gewone ArrayList geprobeerd, 
maar dat werkte ook niet

  • mulder
  • Registratie: Augustus 2001
  • Laatst online: 31-08 15:46

mulder

ik spuug op het trottoir

Ik denk toch dat er iets van een soort refresh/update gedaan moet worden.

oogjes open, snaveltjes dicht


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Hum. Ik ben helaas nog niet zo thuis in deze toestand omdat ik nog geen serieuze WinForms apps heb geschreven. Nu ik dit zo zie: ik zie nergens een constructie die het form ook daadwerkelijk laat luisteren naar de DataSource.

Moet je dat niet zelf doen? De FieldsContainer implementeert namelijk ook geen interface die met 'Observable' te maken hebben, waardoor ik geen standaard methode zie waarop er geluisterd wordt naar de DataSource.

Dat hij het eerst wel doet, komt denk ik met name omdat de data in het component pas na de intializatie ingelezen gaat worden ...

Ik kan er volledig naast zitten omdat ik alleen uit ervaring met andere GUI libs praat ;) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Ik heb maar ff m'n Microsoft Windows PC aangezet om de API documentatie te bekijken, aangezien dit kennelijk toch een lastig oplosbaar probleem is (had wel verwacht dat anderen konden omschrijven hoe je dit moet aanpakken).

In "Building Applications / Creating Windows Forms Applications / Windows Forms Data Architecture / Interfaces Related to Data Binding" kan je lezen dat een DataSource die slechts IList implementeert geen middelen heeft om de Control te informeren over aanpassingen. Dat is ook niet zo verwonderlijk: hiervoor moet je echt wel iets meer hebben dan alleen een lijst.

Als de DataSource als een soort model moet gaan werken zoals je dat bijvoorbeeld in Swing en JFace ziet, moet er een notificatie mechanisme zijn. Hiervoor moet je de IBindingList hebben (namespace System.ComponentsModel). Helaas zie ik in de ListControl class echter niet aangegeven welke zaken je nu precies kan gebruiken als DataSource. De DataSource property is een object en daarbij staat aangegeven dat het de IList moet implementeren of een DataSet moet zijn.

Als ik maar even aanneem dat de IBindingList hier goed functioneert (het lijkt mij erg raar als dat niet zo is) moet je kiezen: of je gaat IBindingList implementeren of je neemt een bestaande implementatie. Ik geloof dat dat laatste echter niet echt een aantrekkelijke optie is omdat je dan gelijk op een DataView uitkomt. Implementeren is dan nog de aantrekkelijkste oplodssing en hoe je dat moet doen staat beschreven in een prachtig voorbeeld in de IBindingList klasse.

Het is heel erg veel (te veel) code en ik denk dat je dat wel wat generieker kan implementeren voor alle lijsten items. Het verbaasd mij eigenlijk dat zo'n implementatie niet standaard beschikbaar is (ik kon hem niet vinden). Je ziet hier wel een fraai voorbeeld van het gebruik van IEditableObject.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • brammetje
  • Registratie: Oktober 2000
  • Laatst online: 12-01-2025
Een beetje laat, maar dan hier de oplossing in code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
public event ListChangedEventHandler ListChanged;

public bool AllowEdit{
    get{
        return true;
    }
}

public bool AllowNew{
    get{
        return true;
    }
}

public bool AllowRemove{
    get{
        return true;
    }
}

public bool IsSorted{
    get{
        throw new NotSupportedException();
    }
}

public ListSortDirection SortDirection{
    get{
        throw new NotSupportedException();
    }
}

public PropertyDescriptor SortProperty{
    get{
        throw new NotSupportedException();
    }
}

public bool SupportsChangeNotification{
    get{
        return true;
    }
}

public bool SupportsSearching{
    get{
        return false;
    }
}

public bool SupportsSorting{
    get{
        return false;
    }
}

public void AddIndex(PropertyDescriptor property){
}

public Object AddNew(){
    throw new NotSupportedException();
}

public void ApplySort(PropertyDescriptor property, ListSortDirection direction){
    throw new NotSupportedException();
}

public int Find(PropertyDescriptor property, object key){
    throw new NotSupportedException();
}

public void RemoveIndex( PropertyDescriptor property ){
    throw new NotSupportedException();
}

public void RemoveSort(){
    throw new NotSupportedException();
}

public void OnListChanged(){
    if ( ListChanged != null )
        ListChanged( this, new ListChangedEventArgs(ListChangedType.Reset, 0 ));
}


Het ListChangedType.Reset is misschien niet heel erg netjes, maar het werkt wel en scheelt me een hoop code ;) Ook zal mijn lijst nooit langer dan 20 items worden.

ow, ik heb natuurlijk ook nog de code om het event te triggeren toegevoegd, maar dat had ik al klaar, hoefde alleen de naam maar te veranderen.
Pagina: 1