ObservableCollection<T> in Winforms und mögliche alternativen
Winforms .net 3.5-app. In meiner app habe ich eine generische Klasse, die sieht so aus:
public class FilterItem {
public FilterItem() { }
public string FilterProperty { get; set; }
public bool FilterPropertyChecked { get; set; }
public ComparitiveOperator FilterOperator { get; set; }
public string FilterValue { get; set; }
}
und ich verwende Sie in allen meinen Dialogfelder, wenn ich will, um zu implementieren eine Art von filter-Funktionen. So nenne ich die dialog-form mit pre-poulated List<FilterItem>
übergeben im Konstruktor. Nun, wenn der dialog geladen, es iteriert durch jeden list-Element und fügt hinzu:
- Eine checkbox
- Eine combobox
- Eine textbox
jede Zeile in ein TableLayoutPanel. Die Checkbox bekommt seine text-Eigenschaft von FilterProperty
und seine Checked-status vom FilterPropertyChecked
...die Combobox erhält Ihre Bindung aus FilterOperator
...und das Textfeld erhält seinen text-Wert von FilterValue
.
Beachten Sie, wie Im nur sagen bekommt. Was ich möchte zu tun ist, aktualisieren Sie automatisch diese Eigenschaften, wenn Sie die Steuerelemente, deren Eigenschaften Sie gebunden sind, zu ändern. Ich hörte ObservableCollection<T>
aber ich nicht zu haben scheinen "Zugriff", um es in Winforms nach dem hinzufügen der System.Collections.ObjectModel
namespace.
Was wäre der beste Weg, dies zu erreichen. BindingList mit INotifyPropertyChanged?? Ich bin nicht ein Experte mit der letzteren, und wäre dankbar ein paar Tipps - wenn das der Weg ich sollte gehen.
thank u!
EDIT:
Ok, lassen Sie mich nach einigen code zu zeigen, was ich glaube, was ich tun sollte :). Ich weiß, ich brauche zu implementieren INotifyPropertyChanged
auf meine FilterItem Klasse, so (nur für die FilterValue Teil zum Beispiel):
public class FilterItem : INotifyPropertyChanged {
public FilterItem() { }
public string FilterProperty { get; set; }
public bool FilterPropertyChecked { get; set; }
public ComparitiveOperator FilterOperator { get; set; }
private string _FilterValue;
public string FilterValue {
get { return this._FilterValue; }
set {
if (this._FilterValue != value) {
this._FilterValue = value;
this.OnFilterValueChanged();
}
}
}
#region INotifyPropertyChanged Members
protected void OnFilterValueChanged() {
var handler = this.PropertyChanged;
if (handler != null) {
handler(this, new PropertyChangedEventArgs("FilterValue"));
}
}
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
Nun sollte alle kommen zusammen in meinem Form_Load (dies ist nur für die Textbox-Teil und die ich ausgelassen habe, die Checbox und ComboBox) etwa so:
private List<FilterItem> FilterList; //<-- this gets assigned to in the constructor
private void dlgFilterData_Load(object sender, EventArgs e) {
foreach (FilterItem item in FilterList) {
txt = new TextBox();
txt.DataBindings.Add("Text", item, "FilterValue", false, DataSourceUpdateMode.OnPropertyChanged);
txt.Dock = DockStyle.Fill;
}
}
dem Textfeld des databindings-Datenquelle ist der FilterItem "Artikel". Aber jetzt scheint es ein problem mit meinem visual studio-IDE, so nicht, dies auszuprobieren, aber wenn ich es zum laufen. Was ich gerne wissen würde ist jetzt: wird das setup erfolgreich zu unterstützen, damit Sie meine individuelle FilterItem
s bekommen automatisch aktualisiert, wenn Ihre zugeordneten Steuerung der jeweiligen Eigenschaft ändert??
InformationsquelleAutor Shalan | 2009-11-23
Du musst angemeldet sein, um einen Kommentar abzugeben.
In die ObservableCollection-Klasse ist in der WindowsBase assembly, so würden Sie brauchen, um hinzuzufügen, WindowsBase zu Ihrem Projekt Verweise auf "Zugriff".
Dass gesagt wird, ich glaube nicht, dass ObservableCollection wird Ihnen alles, was Sie wollen. Die gebundene Steuerelement benachrichtigt werden, wenn Sie Elemente hinzufügen oder entfernen, aber es gibt keine automatische property-änderungs -, das ist, was es klingt wie Sie wollen.
Unabhängig davon, welche Art von Sammlung, die Sie am Ende mit, ich glaube, du bist auf dem richtigen Weg mit INotifyPropertyChanged. Hier ist ein einfaches Beispiel für die Implementierung von INotifyPropertyChanged:
Grundsätzlich, zu jeder Zeit eine Eigenschaft des Objekts ändert, das Feuer, das PropertyChanged-Ereignis, wobei Sie den Namen der geänderten Eigenschaft.
Schließlich, all dies kann umstritten, weil Sie gesagt haben, dass Sie möchten, ändern Sie den Wert einer Objekt-Eigenschaft in Reaktion auf eine änderung an ein Steuerelement gebunden ist, die Eigenschaft. Die üblichen Windows-Forms-Datenbindung Infrastruktur können machen, die geschehen, ohne die Hilfe von INotifyPropertyChanged oder eine andere Schnittstelle. Sie müssen nur die INotifyPropertyChanged implementieren, wenn Sie brauchen, um Benachrichtigen eines gebundenen Steuerelements von änderungen auf die Eigenschaften des Objekts von anderswo.
Wenn Sie die Einrichtung eines zwei-Wege-Datenbindung (der normale Fall) zwischen einem Objekt und einem control, das framework versuchen, zu aktualisieren in Reaktion auf Veränderungen in der anderen. Die databinding-framework bereits weiß, wie zu erkennen, wenn eine Eigenschaft eines eingebauten Steuerelements ändert, so kann es die änderung der gebundenen Eigenschaft der data-source-Objekt ohne weitere Hilfe von Ihnen. Wenn auf der anderen Seite, sind Sie das ändern einer Eigenschaft mit dem Wert des data-source-Objekt im code, das framework nicht wissen, wie um zu erkennen, dass (und aktualisieren Sie das gebundene Steuerelement), es sei denn, Sie richtig INotifyPropertyChanged implementieren.
Bezüglich der Verwendung von BindingList vs-Liste: wenn man Bedenkt, wie Sie den Aufbau Ihrer form, es macht keinen Unterschied. Wenn Sie verbindlich Ihre Sammlung von FilterItem Objekte direkt so etwas wie ein raster oder listbox, BindingList würde es so machen, dass das hinzufügen eines Elements zur collection hinzufügen würde, das gleiche Element, um das raster/listbox und Umgekehrt.
Woah! gerade erholt von 10 Stunden ohne connectivity! Vielen Dank für all den input, Daniel! im froh, Ihnen zu sagen, dass geht den Weg, den ich oben beschrieben definitiv funktionierte für mich, mit einigen tweaks aus dem code 😉 danke für die Hilfe, dude, ich verstehe deine letzten 2 Kommentare!
InformationsquelleAutor Daniel Pratt