Benutzer mit den meisten Antworten
Klasse und Event/handle

Frage
-
Hallo Experten,
die Klassen und Ihre Möglichkeiten ist ein weites Feld um es mit den Worten von G.Grass zusagen. Ich habe mal folgende mini-Klasse definiert.
Public Class Projekt Dim temp As String Public Sub New() temp = InputBox("Neuer Projektname festlegen", "Neues Projekt", "") If temp = "" Then Exit Sub Me.Name = temp End Sub Private _Name As String Public Property Name() As String Get Return _Name End Get Set(ByVal value As String) _Name = value End Set End Property End Class
ich würde nun gerne ein Ereignis definieren nach dem Muster von einer Textbox_TextChanged(...) in Bezug auf das Property Name(). Geht das und wenn ja wo und wie ....
mfg eem monarch
Antworten
-
Hallo,
am einfachsten ist es i. a. die INotifyPropertyChanged Schnittstelle zu verwenden,
siehe Gewusst wie: Implementieren der INotifyPropertyChanged-Schnittstelle
was die Zahl der Ereignisse im Rahmen hält, wenn die Klasse mal nicht mehr so "Mini" ist.Vorteil ist dabei, dass auch die Windows Forms (und WPF) Datenbindung damit umgehen kann,
wie schon mal angedeutet in Array in StrukturvariableVerwendet man explizite Ereignisse, so müssen sie dazu nach dem Muster <Eigenschaftsname>Changed gebildet werden:
Gewusst wie: Anwenden des PropertyNameChanged-Musters
@Markus: Der "_" wäre dabei ein Unterstrich zuviel.
Gruß Elmar
- Als Antwort markiert Monarch-Falter Mittwoch, 22. Februar 2012 14:17
-
Hi Monarch,
hier mal Beispiel für die Implementierung von Implements INotifyPropertyChanged.
Imports System.ComponentModel Public Class Person Implements INotifyPropertyChanged Protected Sub OnPropertyChanged(ByVal name As String) RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(name)) End Sub Public Event PropertyChanged(ByVal sender As Object, ByVal e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged Private mName As String = String.Empty Public Property Name As String Set(ByVal value As String) mName = value OnPropertyChanged("Name") End Set Get Return mName End Get End Property End Class
MFG
Björn
- Als Antwort markiert Monarch-Falter Mittwoch, 22. Februar 2012 14:16
-
Hallo Monarch, du musst Bücher lesen um etwas mit VB.Net zu machen was einfach nur einen Nutzen bringt. Ich war durch diese Zeitung so beunruhigt. Doch ich denke das dieser Hype sehr gelassen gesehen werden kann.
Option Strict On
Imports System
Imports System.IO
Public Class xSituationen
Public Property index As Integer 'Index für Ursprüngliche Reihenfolge
Public Property Situation As String
Public Property Antw As New List(Of String)
Public Property Stil As New List(Of Integer)
Public Property Wert As New List(Of Integer)
Public Property Reife As Integer
End Class
Public Class Projekt
Private mstrName As String = "Property welches gesetzt sein muss."
Private Situation As List(Of xSituationen)
Public ReadOnly Property Name As String
Get
Return mstrName
End Get
End Property
Public Sub New(ByVal pstrName As String)
mstrName = pstrName
Situation = New List(Of xSituationen)
End Sub
Public Sub Read()
Dim i As Integer = 0
Dim objxSituationen As xSituationen
' Variable die den Text aufnimmt
Dim textline As String
' Nun über StreamReader einlesen (ich verwende Using, das räumt sich selbst auf)
Using lese As New System.IO.StreamReader(System.AppDomain.CurrentDomain.BaseDirectory & "\Projekte\" & Me.Name & "\Data\situationen.dat", System.Text.Encoding.Default)
Do While Not lese.EndOfStream
objxSituationen = New xSituationen
i += 1
textline = lese.ReadLine
Debug.Print(textline)
Dim sArray() As String
sArray = Split(textline, "|")
objxSituationen.index = i
objxSituationen.Situation = sArray(0)
objxSituationen.Antw = New List(Of String) From {sArray(1), sArray(2), sArray(3), sArray(4)}
objxSituationen.Stil = New List(Of Integer) From {CInt(sArray(5)), CInt(sArray(6)), CInt(sArray(7)), CInt(sArray(8))}
objxSituationen.Wert = New List(Of Integer) From {CInt(sArray(9)), CInt(sArray(10)), CInt(sArray(11)), CInt(sArray(12))}
Situation.Add(objxSituationen)
Loop
End Using
End Sub
End Class
- Bearbeitet Markus222 Montag, 20. Februar 2012 19:30
- Als Antwort markiert Monarch-Falter Mittwoch, 22. Februar 2012 14:16
Alle Antworten
-
Hallo Monarch,
vielleicht so:
Public Class Projekt
Event Name_Changed()
Dim temp As String = ""
Public Sub New()
temp = InputBox("Neuer Projektname festlegen", "Neues Projekt", "")
If temp = "" Then Exit Sub
Me.Name = temp
End Sub
Private _Name As String = ""
Public Property Name() As String
Get
Return _Name
End Get
Set(ByVal value As String)
Dim blnChanged As Boolean = False
If _Name <> Trim(value) Then
blnChanged = True
End If
_Name = Trim(value)
If blnChanged Then
RaiseEvent Name_Changed()
End If
End Set
End Property
End Class
Public Class Form1
WithEvents Projekt As New Projekt
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Projekt.Name = "Projekt1"
Projekt.Name = "Projekt2"
End Sub
Private Sub Projekt_Name_Changes() Handles Projekt.Name_Changed
MsgBox(Projekt.Name)
End Sub
End Class
-
Hallo,
am einfachsten ist es i. a. die INotifyPropertyChanged Schnittstelle zu verwenden,
siehe Gewusst wie: Implementieren der INotifyPropertyChanged-Schnittstelle
was die Zahl der Ereignisse im Rahmen hält, wenn die Klasse mal nicht mehr so "Mini" ist.Vorteil ist dabei, dass auch die Windows Forms (und WPF) Datenbindung damit umgehen kann,
wie schon mal angedeutet in Array in StrukturvariableVerwendet man explizite Ereignisse, so müssen sie dazu nach dem Muster <Eigenschaftsname>Changed gebildet werden:
Gewusst wie: Anwenden des PropertyNameChanged-Musters
@Markus: Der "_" wäre dabei ein Unterstrich zuviel.
Gruß Elmar
- Als Antwort markiert Monarch-Falter Mittwoch, 22. Februar 2012 14:17
-
-
Hallo Manarch,
Elmas Lösung ist auf jeden fall die Richtige und du solltest sie verwenden.
Was deine Frage angeht, die Deklaration des Events mus auserrhalb des Set´s geschehen, damit eine andere Klasse, ein Handel auf das Event setzen kann.
Das RaiseEvent kann dann im Set gesehen.
Noch eine kleine Anmerkung zum Set vom Markus:
Set(ByVal value As String) Dim blnChanged As Boolean = False If _Name <> Trim(value) Then blnChanged = True End If _Name = Trim(value) If blnChanged Then RaiseEvent Name_Changed() End If End Set End Property End Class
Kann man auch so schreiben:
Set(ByVal value As String) If _Name <> value Then _Name = value RaiseEvent Name_Changed() End If End Set
Erstmal ist es kürzer und einfacher zu lesen.
Zweitens habe ich, das Trim entfernt. Man kann es natürlich machen, aber für mich ändert das Trim, dass Verhalten des Setters ohne dass es für einen anderen Programierer ersichtlich ist. Wenn z.B. der Name bei einen Passwort genutzt wir, kann es durchaus sein das jemand am Anfang ein Leerzeichen benutzt. Hier dann herauszu finden, das dein Setter das Leerzeichen entfernt ist dann nicht ganz Trivial.
Es bietet sich hier der DataErrorProvider (bwz das Interface) an, man könnte auch eine Exeption schmeißen, was ich aber nicht so schön finde.
MFG
Björn
-
Servus Markus,
funzen tut das, ist aber irgendwie doppelt gemoppelt. Innerhalb des Set's wird die Änderung ermittelt und der RaiseEvent ausgelöst. Es würde aber auch nix ändern wenn ich den Event innerhalb des Set's lasse, oder ?
mfg eem monarch
Hallo Monarch,
das verstehe ich nicht. Würde nicht sagen dass es doppelt gemoppelt ist. Du kannst ja einfach probieren und schauen.
-
Ok,
die Antwort von Palin erklärt es. Wenn ich den Event in verschiedenen Klassen benutzen will, muss ich das RaiseEvent verwenden. Ansonsten könnte ich ja folgendes machen (nur als Beispiel)
Set(ByVal value As String)
If _Name <> value Thenif value="x" then _Name="Fehler" else _Name = value
'RaiseEvent Name_Changed()
End If
End Set
-
Hallo Monarch,
es kommt darauf an was du machen willst. Die einfachste und am einfachsten zu lesenste Lösung ist im Zweifelsfalle meiner Meinung nach die Beste. Das "State of the Art" oder wie man es nennen mag zieht im Quellcode immer ein Nichtverstehen nach sich. Man muss lange suchen. Der Quellcode erklärt sich nicht mehr selbst. Je mehr davon du nimmst desto mehr must du suchen nach einigen Monaten und Jahren um es wieder zu kapieren. Je einfacher und nativer VB du nimmst und dabei so kurz wie möglich desto einfacher ist dein Programm zu verstehen.
-
Na prima,
bin nur am kämpfen, folgender Code führt zu Fehlermeldungen, wenn ich z.B xSituationen.index einen Wert zuweise. Ich lese nun seit stunden auch das von Elmar aber komme nicht dahinter. Wenn ich das ganze ohne Klassen und List - Objekten schreibe, geht das fix und funzt ... macht man aber nicht mehr, hab ich mir sagen lassen.
Also, wo liegt der Fehler .....
Imports System Imports System.IO Public Class xSituationen Public Property index As Integer 'Index für Ursprüngliche Reihenfolge Public Property Situation As String Public Property Antw As New List(Of String) Public Property Stil As New List(Of Integer) Public Property Wert As New List(Of Integer) Public Property Reife As Integer End Class Public Class Projekt Inherits List(Of xSituationen) Public Sub Read() Dim i As Integer = 0 Dim Situation As New List(Of xSituationen) ' Variable die den Text aufnimmt Dim textline As String ' Nun über StreamReader einlesen (ich verwende Using, das räumt sich selbst auf) Using lese As New System.IO.StreamReader(System.AppDomain.CurrentDomain.BaseDirectory & "\Projekte\" & Me.Name & "\Data\situationen.dat", System.Text.Encoding.Default) Do While Not lese.EndOfStream i += 1 textline = lese.ReadLine Debug.Print(textline) Dim sArray() As String sArray = Split(textline, "|") xSituationen.index = i xSituationen.Situation = sArray(0) xSituationen.Antw = New List(Of String) From {sArray(1), sArray(2), sArray(3), sArray(4)} xSituationen.Stil = New List(Of Integer) From {CInt(sArray(5)), CInt(sArray(6)), CInt(sArray(7)), CInt(sArray(8))} xSituationen.Wert = New List(Of Integer) From {CInt(sArray(9)), CInt(sArray(10)), CInt(sArray(11)), CInt(sArray(12))} Situation.Add(xSituationen) Loop End Using End Sub 'Public Sub
-
Hi Monarch,
hier mal Beispiel für die Implementierung von Implements INotifyPropertyChanged.
Imports System.ComponentModel Public Class Person Implements INotifyPropertyChanged Protected Sub OnPropertyChanged(ByVal name As String) RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(name)) End Sub Public Event PropertyChanged(ByVal sender As Object, ByVal e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged Private mName As String = String.Empty Public Property Name As String Set(ByVal value As String) mName = value OnPropertyChanged("Name") End Set Get Return mName End Get End Property End Class
MFG
Björn
- Als Antwort markiert Monarch-Falter Mittwoch, 22. Februar 2012 14:16
-
Hallo Monarch, du musst Bücher lesen um etwas mit VB.Net zu machen was einfach nur einen Nutzen bringt. Ich war durch diese Zeitung so beunruhigt. Doch ich denke das dieser Hype sehr gelassen gesehen werden kann.
Option Strict On
Imports System
Imports System.IO
Public Class xSituationen
Public Property index As Integer 'Index für Ursprüngliche Reihenfolge
Public Property Situation As String
Public Property Antw As New List(Of String)
Public Property Stil As New List(Of Integer)
Public Property Wert As New List(Of Integer)
Public Property Reife As Integer
End Class
Public Class Projekt
Private mstrName As String = "Property welches gesetzt sein muss."
Private Situation As List(Of xSituationen)
Public ReadOnly Property Name As String
Get
Return mstrName
End Get
End Property
Public Sub New(ByVal pstrName As String)
mstrName = pstrName
Situation = New List(Of xSituationen)
End Sub
Public Sub Read()
Dim i As Integer = 0
Dim objxSituationen As xSituationen
' Variable die den Text aufnimmt
Dim textline As String
' Nun über StreamReader einlesen (ich verwende Using, das räumt sich selbst auf)
Using lese As New System.IO.StreamReader(System.AppDomain.CurrentDomain.BaseDirectory & "\Projekte\" & Me.Name & "\Data\situationen.dat", System.Text.Encoding.Default)
Do While Not lese.EndOfStream
objxSituationen = New xSituationen
i += 1
textline = lese.ReadLine
Debug.Print(textline)
Dim sArray() As String
sArray = Split(textline, "|")
objxSituationen.index = i
objxSituationen.Situation = sArray(0)
objxSituationen.Antw = New List(Of String) From {sArray(1), sArray(2), sArray(3), sArray(4)}
objxSituationen.Stil = New List(Of Integer) From {CInt(sArray(5)), CInt(sArray(6)), CInt(sArray(7)), CInt(sArray(8))}
objxSituationen.Wert = New List(Of Integer) From {CInt(sArray(9)), CInt(sArray(10)), CInt(sArray(11)), CInt(sArray(12))}
Situation.Add(objxSituationen)
Loop
End Using
End Sub
End Class
- Bearbeitet Markus222 Montag, 20. Februar 2012 19:30
- Als Antwort markiert Monarch-Falter Mittwoch, 22. Februar 2012 14:16
-
z.B.
http://www.amazon.de/gp/offer-listing/382732646X/ref=sr_1_3_olp?ie=UTF8&qid=1329770603&sr=8-3&condition=new
Ich glaube je umfangreicher die Sprache wird desto mehr stürzen sich die (oft altgedienten) Autoren auf die neuen Features und wälzen diese über Gebühr breit. Mehr Seiten als wirklichen Nutzen. Das worüber früher Bücher geschrieben wurden (wie z.B. Vererbung und andere objektorientierte Konzepte) wird auf ein paar Seiten abgehandelt und kann in seiner revolutionären Bedeutung von Neulingen gar nicht durch das Buch erfasst werden. Evtl. wäre es daher für einen echten Einsteiger in VB.Net wirklich gut mit einem Buch von VB.Net 2005 zu beginnen. Und dann eben ein Buch zu 2008 und danach eins zu 2010.
-
Fehlermeldung
Der Verweis auf einen nicht freigegeben Member erfordert einen Objektverweis....
Bringt mich nicht weiter .... dich vielleicht
Hätte ich beine Übersehen. ;)
Ich denke, dass ist der Punkt den ich oben schon angesprochen haben.
Du must dier eine Instanz des Objektes erzeugen.
Füge mal an anfang der Sclheife das ein:
private tempxSituationen as xSituation = new Situation()
und ersetze in der Schleife xSituation durcfh tempxSituation.
Damit erzeugst du bei jedem Schleifen durchlauf ein neues Objekt von xSituation (Ich denk mal das möchtest du hier machen).
Wenn du es vor der Schleife machst fügst du der Liste immer das gleiche Objekt hinzu.
Dann hast du zwar x Verweise in der Liste aber immer auf der gleiche Objekt, welches die gleichen Werte hat.
MFG
Björn
-
Also erstmal danke allen,
funzt jetzt ... Da ich mich zwanghaft mit dem VB beschäftigen muss, habe ich halt die Probleme. Ich komme aus der DB-Ecke. Anyway, habe mich mit einen Pratiker unterhalten, der mir folgendes gesagt hat zum Thema Klassen und Neuerungen in VB. Man sollte nicht alles zur Religion erheben bzw. man sollte nicht mit einem 40 to ein Kasten Bier abholen. Klassen haben ihre Vorteile, welche aber in Single-, Klein etc. Programme oft mit zuviel Aufwand verbunden sind. Außerdem muss man nicht alles und jedes als Objekt behandeln bzw. definieren.
trotzdem, werde ich mich weiter bemühen ... danke mfg eem Monarch.
PS: Das nächste Problem kommt bestimmt, werde jetzt erstmal versuchen, die Klasse voll funiktionsfähig zu machen. :-)