Autor Beitrag
DMW007
Hält's aus hier
Beiträge: 7



BeitragVerfasst: Do 18.03.10 02:23 
Hi,

ich moechte in einer seperaten Klasse ein Event mit Argumenten erstellen.

Das ganze soll so funktionieren:

In besagter Klasse habe ich einen String, der anfangs leer ist und zu Laufzeit einen Wert annimmt. Nun soll ein Event genau dann reagieren wenn der Wert des Strings sich veraendert, sprich nichtmehr null ist. Im Event soll der String dann uebergeben werden, sodass auf ihn zugegriffen werden kann.

Der Aufruf der Klasse in meinem Programm sollte dann etwa so aussehen:

ausblenden C#-Quelltext
1:
2:
3:
// Neue Instanz der Klasse
TestClass myTest = new TestClass();
myTest.OnStringChanged += OnStringChanged;


Die Methode OnStringChanged

ausblenden C#-Quelltext
1:
2:
3:
4:
private void OnStringChanged(string myString)
{
MessageBox.Show(myString);
}


In der Methode kann man dann auf den String zugreifen (im Beispiel der String "myString"), die Methode soll aufgerufen werden wenn sich besagter String eben in der seperaten Klasse (im Beispiel "myTest") aendert.

Ich hoffe es ist verstaendlich um was es geht, Man kann es vergleichen wie mit dem OnTextChanged Event einer TextBox, nur dass ich eben einen String als Parameter uebergeben will... Standardmaessig wird ja nur SystemArgs uebergeben :s

Ich habe noch nie mit Events gearbeitet, daher waere ich ueber eine gute Erklaerung sehr dankbar :)

Moderiert von user profile iconChristian S.: Code- durch C#-Tags ersetzt
JüTho
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2021
Erhaltene Danke: 6

Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
BeitragVerfasst: Do 18.03.10 10:11 
Hallo,

du kommst von Delphi, nicht wahr? Unter .NET heißt das Ereignis selbst TextChanged, mit OnTextChanged wird eine Methode bezeichnet, die das Ereignis auslöst.

Ein EventHandler (also das, was du beim Aufruf der Klasse mit += anhängst) muss immer so deklariert werden:
ausblenden C#-Quelltext
1:
... XxxChanged(object sender, EventArgs e)					

Dabei kann auch eine Erweiterung von EventArgs benutzt werden. sender ist immer (!) der Auslöser des Ereignisses, bei dir also vermutlich die Instanz deiner Klasse. Damit hast du zwei Möglichkeiten:

1. Abfragen, wer der sender ist (also welche Instanz von TestClass), und dessen Wert abfragen; der Wert Value muss natürlich als Eigenschaft (ggf. readonly) zur Verfügung gestellt werden.
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
private void StringChanged(object sender, EventArgs e)
{
  TestClass current = sender as TestClass;  // Sicherheitsprüfung
  if (current != null) {
    MessageBox.Show(current.Value);
  }
}


2. Eine Ableitung von EventArgs erstellen, die den aktuellen Wert des Textes enthält (analog dazu, wie bei den Mouse-Ereignissen X,Y zur Verfügung gestellt werden). Dann kann der Text direkt mit e.Value ausgelesen werden.

In beiden Fällen muss die Methode OnStringChanged innerhalb deiner Klasse aufgerufen werden immer dann, wenn sich der Text ändert - je nachdem mit "leeren" EventArgs (Variante 1) oder mit speziellem StringEventArgs (Variante 2).

Siehe in der SDK-Doku/MSDN/Hilfe unter Auslösen von Ereignissen.

Gruß Jürgen

PS. Für die Markierung von Code gibt es in der ComboBox unter "Bereiche" die Auswahl C#. Bitte benutze in der Regel dies. (Code ist gedacht für Pseudo-Code und für Fälle, für die keine besondere Syntax registriert ist.)

PS 2 (um 12:29 Uhr): Ich hoffe, es ist dir bewusst, dass Strings unter .NET unveränderlich sind ("Referenztypen mit dem Verhalten eines Wertetypen"). Jegliche Änderung eines Strings führt zum Umkopieren im Arbeitsspeicher. Ich könnte mir vorstellen, dass dein Vorgehen dich dazu verleitet, diese Eigenheit zu nutzen und damit das System stärker zu belasten als sinnvoll.


Zuletzt bearbeitet von JüTho am Do 18.03.10 13:31, insgesamt 1-mal bearbeitet
danielf
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: Do 18.03.10 10:51 
Hallo,

nach dem ersten Teil war mir klar, was du willst... nach dem ich den zweiten gelesen habe nicht mehr :) Ich werde deshalb mal den ersten beantworten und du kannst ja dann Bescheid sagen ob es dir hilft.

Ach, sehe gerade Jürgen war schneller ...

Dann geh ich mal genauer auf deine TestClass ein.

ausblenden C#-Quelltext
1:
2:
3:
public class TestClass {
public string EventString { get; set; }
}


Ich gehe davon aus, das sie "so ähnlich" aufgebaut ist und du einfach ein Event feuern willst,wenn der string einen neuen Wert annimmt. Dafür musst du zuerst das Event deklarieren.
ausblenden C#-Quelltext
1:
public even EventHandler EventStringChanged;					


Nun musst du, wenn der Wert geändert wird genau dieses Event auslösen. Deshalb passt du den Set-Teil des Properties an:
(Weil du den Set-Teil selber implementierst musst du auch den Get teil selber implementieren und dir das Ergebnis merken)
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
private string _eventString;
public string EventString {
get { return _eventString; }
set { 
// neuer wert merken
_eventString = value;
// event auslösen (falls jemand darauf registriert ist)
if (EventStringChanged != null)
{
   EvenStringChanged(thisnull);
}
}


So hättest du dein Event deklariert und feuerst es, wenn der string "EventString" neu gesetzt, bzw. geändert wird.

Wenn ich dich richtig verstanden habe, willst du den geänderten string gleich dem Event mitgeben. Deshalb musst du die Event-Deklaration anpassen. Da der EventHandler nur als Parameter ein EventArgs akzeptiert musst du eine neue Klasse erstellen, die von EventArgs erbt:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
public StringEventArgs : EventArgs
prublic string String { get ;set; }
public StringEventArgs (string value)
{
   String = value;
}
}


In der Deklaration kannst du dann dieses Objekt angeben:
ausblenden C#-Quelltext
1:
public event EventHandler<StringEventArgs> EventStringChanged;					


Auslösen tust du es dann:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
private string _eventString;
public string EventString {
get { return _eventString; }
set { 
// neuer wert merken
_eventString = value;
// event auslösen (falls jemand darauf registriert ist)
if (EventStringChanged != null)
{
   EvenStringChanged(thisnew StringEventArgs(_eventString));
}
}


Die Verwendung hat dir ja Jürgen gezeigt.

Viel Erfolg,
Gruß Daniel