Hallo zusammen,
im Thread EventHandler empfängt Eventfeuerung nicht zuverlässig habe ich es angedeutet: Ich will den Umgang mit der INotifyPropertyChanged-Schnittstelle vereinfachen. Dazu habe ich inzwischen folgendes:
Die Basisklasse, welche man später abgeleitet nutzt:
Spoiler anzeigen
Die GenericProperty-Klasse
Spoiler anzeigen
Das Minihilfsinterface
Eine abgeleitete Klasse, die man im Hauptprogramm nutzen würde
die Verwendung
das Problem
Die durch den überladenen Shared-Implicit-Cast-Operator CType erstellte neue Instanz muss jetzt irgendwie der SimpleNotifyingClass bescheid geben, dass sie existiert. Aber eben erst, wenn die bestehende Property ersetzt wurde. Nicht dass jemand schreibt:
und dass dann gar nicht an die SimpleNotifyingClass-Instanz weitergibt. Wie kann ich also den Ersatz der bestehenden SimpleNotifyingClass-Instanzproperty erfassen?
Ich habe es natürlich schon mit einer
im Thread EventHandler empfängt Eventfeuerung nicht zuverlässig habe ich es angedeutet: Ich will den Umgang mit der INotifyPropertyChanged-Schnittstelle vereinfachen. Dazu habe ich inzwischen folgendes:
Die Basisklasse, welche man später abgeleitet nutzt:
VB.NET-Quellcode
- Public MustInherit Class SimpleNotifyingClass : Implements ComponentModel.INotifyPropertyChanged
- Public Event PropertyChanged As ComponentModel.PropertyChangedEventHandler Implements ComponentModel.INotifyPropertyChanged.PropertyChanged
- Protected Sub New()
- WireEvents()
- End Sub
- Private Async Sub WireEvents()
- Await Threading.Tasks.Task.Run(Sub() WaitForInitializing())
- For Each NotifyingProperty In Me.GetType.GetProperties.Where(Function(x) x.PropertyType.GetInterface(NameOf(ComponentModel.INotifyPropertyChanged)) IsNot Nothing)
- AddHandler DirectCast(NotifyingProperty.GetValue(Me), ComponentModel.INotifyPropertyChanged).PropertyChanged, AddressOf PropertyChangedEventReporter
- Next
- For Each MortalProperty In Me.GetType.GetProperties.Where(Function(x) x.PropertyType.GetInterface(NameOf(IMortal)) IsNot Nothing)
- AddHandler DirectCast(MortalProperty.GetValue(Me), IMortal).IsDying, AddressOf RegisterPropertyDeath
- Next
- End Sub
- Private Sub WaitForInitializing()
- Dim FirstNotifyingProperty = Me.GetType.GetProperties.FirstOrDefault(Function(x) x.PropertyType.GetInterface(NameOf(ComponentModel.INotifyPropertyChanged)) IsNot Nothing)
- If FirstNotifyingProperty Is Nothing Then Return
- Do Until FirstNotifyingProperty.GetValue(Me) IsNot Nothing : Loop
- End Sub
- Private Sub PropertyChangedEventReporter(sender As Object, e As ComponentModel.PropertyChangedEventArgs)
- RaiseEvent PropertyChanged(Me, New ComponentModel.PropertyChangedEventArgs(String.Empty))
- End Sub
- Private Sub RegisterPropertyDeath(sender As Object, e As EventArgs)
- PropertyChangedEventReporter(Me, New ComponentModel.PropertyChangedEventArgs(String.Empty))
- End Sub
- End Class
Die GenericProperty-Klasse
VB.NET-Quellcode
- Public Class GenericProperty(Of T) : Implements ComponentModel.INotifyPropertyChanged, IMortal
- Public Event PropertyChanged As ComponentModel.PropertyChangedEventHandler Implements ComponentModel.INotifyPropertyChanged.PropertyChanged
- Public Event IsDying As EventHandler Implements IMortal.IsDying
- Private _Value As T
- Public Property Value As T
- Get
- Return _Value
- End Get
- Set
- If _Value.Equals(Value) Then Return
- _Value = Value
- NotifyPropertyChanged()
- End Set
- End Property
- Private Sub NotifyPropertyChanged(<Runtime.CompilerServices.CallerMemberName> Optional Name As String = Nothing)
- RaiseEvent PropertyChanged(Me, New ComponentModel.PropertyChangedEventArgs(Name))
- End Sub
- Public Shared Widening Operator CType(Value As T) As GenericProperty(Of T)
- Return New GenericProperty(Of T) With {._Value = Value}
- End Operator
- Public Shared Widening Operator CType(Base As GenericProperty(Of T)) As T
- Return Base.Value
- End Operator
- Public Overrides Function ToString() As String
- If _Value Is Nothing Then Return Nothing
- Return _Value.ToString
- End Function
- Protected Overrides Sub Finalize()
- RaiseEvent IsDying(Me, Nothing)
- End Sub
- End Class
Das Minihilfsinterface
Eine abgeleitete Klasse, die man im Hauptprogramm nutzen würde
die Verwendung
VB.NET-Quellcode
- Dim TestInstance As Test = Nothing
- Private Sub FrmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
- TestInstance = New Test
- BindingSource1.DataSource = TestInstance
- End Sub
- Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
- TestInstance.ID = 1
- GC.Collect()
- End Sub
GC.Collect()
ruft die GenericProperty-Finalize-Sub auf, die dann dafür sorgt, dass die GenericProperty der SimpleNotifyingClass bescheid gibt, dass sie ersetzt wurde, also dass das INotifyPropertyChanged.PropertyChanged-Event gefeuert werden muss und z.B. eine BindingSource davon erfährt. Das ist nicht besonders schön, aber erstmal die einzige Möglichkeit, wie ich dafür sorgen kann, dass die SimpleNotifyingClass-Instanz davon erfährt, dass eine bestehende Property ersetzt wurde.das Problem
Die durch den überladenen Shared-Implicit-Cast-Operator CType erstellte neue Instanz muss jetzt irgendwie der SimpleNotifyingClass bescheid geben, dass sie existiert. Aber eben erst, wenn die bestehende Property ersetzt wurde. Nicht dass jemand schreibt:
und dass dann gar nicht an die SimpleNotifyingClass-Instanz weitergibt. Wie kann ich also den Ersatz der bestehenden SimpleNotifyingClass-Instanzproperty erfassen?
Ich habe es natürlich schon mit einer
ObservableCollection(Of INotifyPropertyChanged)
probiert, aber das klappt (natürlich) nicht, da diese die Ersetzung nicht erkennt, wenn man ein Item der Collection direkt ersetzt.Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.
Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()