Laden...

Forenbeiträge von epic_fail Ingesamt 33 Beiträge

13.12.2011 - 15:41 Uhr

"Das lohnt sich nicht, es wird ja nur einmal entwickelt. Wenn es erstmal läuft, hast du nichts mehr damit zu tun" 😄

13.12.2011 - 14:22 Uhr

Im Ernst: Probleme mit der Motivation fuer so Legacy Projekte habe ich nicht, im Gegenteil - mir macht es Spaß, sowas aufzuraeumen und ordentlich glatt zu ziehen.

Das würde mir auch Spass machen. Leider fehlt es immer an Geld. Den Kunden ist es egal, wie der Code aussieht. Hauptsache es funktioniert. Mein Chef sieht das genau so. Ist halt ein Unternehmer und kein Entwickler. Somit bleibt mir fast nie etwas anderes übrig als Flickwerk, weiteres Flickwerk hinzuzufügen.

13.12.2011 - 13:36 Uhr

Monster Energy und Speedmetal.

LOL!! Naja wems hilft... Ich mag beides nicht =D

13.12.2011 - 13:26 Uhr

Ich liebe meinen Job und meinen Beruf. Aber es gibt Aufgaben, da habe ich extreme Schwierigkeiten in die Puschen zu kommen und schiebe sie immer - zugunsten von interessanteren Aufgaben - auf. Das ist vor allem dann, wenn es darum geht (fremde) uralte Projekte aufzuwärmen ("Neue" Bugs fixen, neue Features implementieren usw.).

Wie könnt ihr euch da motivieren?

Edit: Es geht mir eigentlich ähnlich wie dem Threadersteller von hier: Wie kann man sich selbst zum Programmieren motivieren?. Nur dass ich keine Blockade habe, sondern es mich mich einfach angurkt oder sogar nervt (Bei so richtig üblen altem Schrott).

13.12.2011 - 13:11 Uhr

Ich würde beim runterscrollen die jeweils anzuzeigenden Elemente nachladen (Lazy Loading)

13.12.2011 - 10:29 Uhr

ich hab nun z.b. folgenden dateiname mit mein programm auf den PC entdeckt
testdatei_12.12.12.xls
oder
testdatei 12.12.12.xls

anhand diesen dateinahmen möchte ich jetzt den richtigen Datensatz in der SQL datenbank suchen.

Und welchen der Beispieldatensätze die du gepostet hast müsste deine Abfrage dann zurückliefern? Ich sehe keinen der passt.

Sprich mit dem längeren wort such ich das kürzere nicht wie normalerweise mit dem kürzeren das längere.

Jedoch soll das ganze ohne Splitten des Dateinamen passieren. 😉

Welches ist das längere und welches das kürzere Wort? Und was genau meinst du mit splitten des Dateinamens?

12.12.2011 - 17:32 Uhr

Poste mal bitte deine Tabelle mit ein paar Beispieldaten. Ich peil leider nicht ganz was du hier versuchst 😉

12.12.2011 - 15:36 Uhr

Wieso soll LIKE nicht funktionieren?

SELECT * FROM [Tabelle] WHERE FileName LIKE 'test%.xls'
18.10.2011 - 11:52 Uhr

wenn das Remote-Fenster nicht maximiert ist, also Windowstate=Normal, gehts bei mir mit Alt Gr.

Habe die RDP Verbindung in einem Fenster aufgebau und nicht im Vollbild. Leider behebt es das Problem bei mir trotzdem nicht.

Mittlerweile musste ich feststellen, dass Strg + ALT auch nicht immer funktioniert. Ich habe aber jetzt rausgefunden, dass wenn man länger (1-2 Sekunden) auf die Taste drückt, es jedes Mal klappt. Das gilt für ALT GR sowie auch für Strg + ALT. Wenn ich zu schnell bin, ist es wie wenn RDP nicht mitbekommt, dass ALT auch gedrückt wurde. Das kann ich im Visual Studio links unten in der Ecke sehen. Wenn ich z.B. die öffnende geschweifte Klammer einfügen will, steht da

(Ctrl+ä) was pressed. Waiting for second key of chord

Korrekt wäre ja Ctrl+ALT+ä, was die Tastenkombination für die öffnende geschweifte Klammer ist.

18.10.2011 - 09:19 Uhr

Ich habe folgendes Problem: KB926934: You cannot use a keyboard shortcut that uses the ALT GR key in a Terminal Services session that connects to a Windows Server 2003-based terminal server

Anstatt ALT GR die Kombination Strg+ALT zu nutzen funktionert zwar theoretisch, in meinem Kopf allerdings nicht.

Die andere Lösung geht gar nicht. Ich bin genau nach Anleitung vorgegangen. Habe alle Geräte neu gestartet, aber keine Veränderung festegestellt.

Wer hat Erfahrungen mit dem Problem? Was gibt es für weitere Möglichkeiten?

07.07.2011 - 13:25 Uhr

Direkt hier gefunden habe ich nichts. Es gibt aber das IsReadOnly-Attribut von der FileInfo-Klasse.

Momentan sehe ich vor allem einen try/catch Block. Der den Vorgang n-mal wiederholt bei einer IOException.

07.07.2011 - 12:01 Uhr

Du musst die Eventargs auswerten. Es ist so, wie herbivore es sagt. Das reine Öffnen ist das erste Event. Das Manipulieren des Inhaltes ist das zweite Event.

Ich habe etwas in der Richtung vermutet. Das scheint wohl so zu sein.

Das kannst du nur, wenn die Telefonanlage mitspielt und beim Öffnen der Datei einen passenden/ausreichenden FileShare-Modus verwendet. Den gleichen musst du dann auch in deinem Programm verwenden.

Gibt es eine Funktion, um bei einem File "anzufragen", ob es gerade verwendet wird? Damit könnte man ja warten, bis das File wieder freigegeben ist, es dann kopieren und mit der Kopie in Ruhe weiterarbeiten.

07.07.2011 - 11:22 Uhr

Hallo Zusammen,

Ich will eine LogDatei von einer Telefonanlage überwachen. Bei Änderung des Files wird aber der Changed-Event zweimal ausgelöst. Warum?


class Program
{
    static void Main(string[] args)
    {
        InitFileSystemWatcher();
        System.Console.Read();
    }

    private static void InitFileSystemWatcher()
    {
        var fsw = new FileSystemWatcher { Path = @"C:\Temp", Filter = "test.log" };
        fsw.Changed += OnChanged;
        fsw.EnableRaisingEvents = true;
    }

    private static void OnChanged(object sender, FileSystemEventArgs e)
    {
        System.Console.WriteLine("Access: " + Guid.NewGuid());
    }
}

Zusätzlich zur Überwachung will ich Daten aus diesem File auslesen. Der Zugriff der Telefonanlage auf dieses File kann ich nicht steuern. Wie kann ich verhindern, dass die Telefonanlage das File nicht beschreiben kann, weil mein Programm gerade daruf zugreift um Daten auszulesen?

31.05.2010 - 09:21 Uhr

OK das funktioniert zumindest. Vielen Dank dafür!

Das erzeugte SQL nutzt das IN keyword:

[...] WHERE ([t0].[Tabelle] IN (@p0, @p1) [...]

Was wäre nun das AND Äquivalent. Ich habe das Gefühl, es gibt noch weitere Möglichkeiten.

31.05.2010 - 08:28 Uhr

verwendetes Datenbanksystem: MSSQL 2005

Ich möchte gerne per LINQ auf eine Tabelle zugreifen und dynamisch eine WHERE Klausel hinzufügen. Wenn es mehrere Bedingungen gibt, soll das WHERE dynamisch um ORs erweitert werden.

Hier ein bisschen Dummycode, oder besser, wie ich es gelöst hätte ohne LINQ. Vielleicht ist es damit besser verständlich.


public string GetSomething(string[] bedingungen)
{
	var sb = new StringBuilder();

	// 1. Teil des Statements
	sb.Append("SELECT * FROM Tabelle");

	// Wenn es Bedingungen gibt, muss ein WHERE in das Statement
	if (bedingungen.Length > 0)
	{
		// Hier kommt das WHERE
		sb.Append(" WHERE ");

		// Es gibt so viele ORs wie Bedingungen
		for (int i = 0; i < bedingungen.Length; i++)
		{
			// Beim 1. Mal brauchts kein OR
			if (i > 0)
				sb.Append(" OR ");

			sb.Append("Attribut = " + bedingungen[i]);
		}
	}

	return sb.ToString();
}


// output: SELECT * FROM Tabelle
GetSomething(null); 
	
// output: returns SELECT * FROM Tabelle WHERE Attribut = B1
GetSomething(new[] { "B1" }); 
	
// output: returns SELECT * FROM Tabelle WHERE Attribut = B3 OR Attribut = B4
GetSomething(new[] { "B3", "B4" }); 

Ich habe keine Ahnung wo ich da ansetzen muss. Ich hoffe Ihr könnt mir da ein wenig weiterhelfen.

23.03.2010 - 14:15 Uhr

Im Netz findest du genügend solcher Beispiele

http://www.google.ch/search?q=drag+and+drop+mit+javascript

23.03.2010 - 09:43 Uhr

OWA ist eine ASP.NET Applikation. Und natürlich ist auch JavaScript im Einsatz (z.B. für Drag&Drop)

Mir scheint, dir ist nicht ganz klar wie viel Arbeit das ist. Hast du bereits andere (Web-)Projekte realisiert? Musst du das alleine machen? Wenn ja, warum? Es gibt doch so schöne fertige (u.a. auch kostenlose) Webmail Software.

30.11.2009 - 13:47 Uhr

@Peter

Dann wäre ich wieder bei meinem Punkt 3... das sieht nicht gut aus und fühlt sich auch nicht gut an...

Helper:
return "<script type=&quot;text/javascript&quot;>$(document).ready(function() {$(&quot;#" + param1 + "&quot;).click(function() {$(&quot;#" + param2 + "&quot;).dialog(&quot;open&quot;);}); usw..."

Ich hab vor etwas mehr als 1 Jahr mal in Ruby on Rails reingeschnuppert. Und da gibt es ein Konzept, dass sich Partials (musste jetzt auch erst suchen bis es mir wieder eingefallen war 🙂) nennt.

http://addictedtonew.com/archives/149/a-bit-on-rails-partials/

Eigentlich ist es genau das, was ich suche 😁

30.11.2009 - 13:29 Uhr

So wie ich das verstehe, muss ich eine Klasse erstellen, die von ViewPage erbt. Eine eigene Methode in dieser Klasse kümmert sich dann um das ausliefern des JavaScripts. Eine solche Klasse passt weder zu den Controllern noch zu den Helpern, sondern wäre vom Sinn her am ehesten nahe bei der View einzuordnen, womit wir bei einer Art Code-Behind landen.

30.11.2009 - 13:09 Uhr

Dann sind wir ja wieder bei Code-Behind Dateien 🙄

30.11.2009 - 11:11 Uhr

Moin,

Ich beschäftige mich seit etwa 2 Wochen mit ASP.NET MVC. Die Abwechslung von den WebForms gefällt mir gut. Wahrscheinlich weil ich aus der PHP Ecke komme und sich ASP.NET MVC einfach etwas mehr nach "Web" anfühlt.

Jetzt ist es ja so, dass man ja seine Views möglichst "Dumm" halten sollte und mit (Html)Helper arbeiten. Nun habe ich aber ein Problem mit Javascripts. Wie soll ich diese einbinden ohne dass ich genanntes Prinzip nicht verletze. Nehmen wir mal an ich will per JavaScript ein Confirmation-Dialog erstellen. Ich sollte dieses Javascript auf verschiedenen Seiten verwenden können, mit verschiedenen Fragestellungen für die Confirmation.

1. Direkt in der View mit einem Script-Tag umschlossen?
Problem: Verletzt das DRY-Prinzip, da ich den JS Code auf mehreren Seiten verwenden will, und dann jedes mal ausschreiben muss.

2. In einem .js-File und in der View referenziert?
Problem: Man kann keine Parameter (z.B. den Text der Fragestellung) übergeben.

3. Als HtmlHelper?
Problem: Der Code ist im Nachhinein nur noch schwer zu ändern. Stichwort: Maskierte Zeichen.

Gibt es da irgendwelche Best Practice Ansätze. Ich hab im Netz nur Ideen mit RenderPartials u.Ä. gefunden. Aber diese scheinen mir nicht komplett fertig gedacht zu sein...

19.11.2009 - 08:38 Uhr

verwendetes Datenbanksystem: MSSQL 2008

Ist es korrekt zwischen zwei Tabellen mehrere Beziehungen herzustellen? Also beispielsweise bei einem Forum mit PM-Funktion.

Tabelle: PM
PmId
FromUserId
ToUserId
MessageText

FromUserId und ToUserId wären dann Fremdschlüssel die jeweils aus einer 0..* Beziehung zu UserId einer Tabelle "User" entstehen. So könnte man sicherstellen, dass die PM immer einen gültigen User als Absender und Empfänger hat. Ich weiss nicht wie ich es anders machen soll, andererseits bin ich unsicher ob dieses Vorgehen richtig ist.

26.06.2009 - 09:40 Uhr

Hallo,

  
delete from Logs where Date < '2009-01-01'  
  

dürfte ohne Probleme funktionieren? Wo genau ist dein Problem.
Du könntest z.N. auch

  
DELETE FROM Logs WHERE Date < GETDATE() - 30  
  

schreiben. Das löscht alle Einträge die Älter als 30 Tage.

Das 2. Statement hat geklappt. Vielen Dank!

26.06.2009 - 09:05 Uhr

verwendetes Datenbanksystem: MSSQL 2005

Um alte Logs in einer Datenbank automatisiert zu löschen habe ich eine Stored Procedure gemacht. Allerdings ist das Ding ziemlich langsam. Ich schiebe das auf den Cursor.

ALTER PROCEDURE [dbo].[sp_LogMaintenance]
	-- Erlaubtes Alter der Logeinträge
	@AllowedAge int 
AS
BEGIN

declare @Age int

declare @CurrentDate datetime
declare LOGLIST cursor fast_forward for
	select Date from Logs

open LOGLIST 
	fetch next from LOGLIST into @CurrentDate 
	while @@fetch_status = 0
	begin
		set @Age = datediff(month, @CurrentDate , getdate())
		if (@Age > @AllowedAge)
		begin
			delete from Logs where Date = @CurrentDate 
		end
		fetch next from LOGLIST into @CurrentDate 
	end			
close LOGLIST 
deallocate LOGLIST 

END

Gibt es keine andere Möglichkeit ein Datum zu vergleichen. Bevor ich angefangen habe, dachte ich man kann relativ einfache deletes absetzen wie:


delete from Logs where Date < '2009-01-01'
09.06.2009 - 09:41 Uhr

Ich hoffe ich darf diesen Thread benutzen. Der Titel ist mir in der SuFu aufgefallen, der Thread beantwortet aber meine Frage nicht.

Ist vielleicht eine Frage des Geschmacks.... Wie soll ich beim Aufruf einer Methode benachrichtigen wenn etwas schief gegangen ist?

Variante 1


public void IrgendwasMachen()
{
    Adresse adresse = new Adresse(new Guid("D3667F33-F0AB-4367-9613-AAF70F9631B3"));
    adresse.Nachname = "Meyer";
    adresse.Update();

    if (adresse.IsUpdated)
    {
        //..
    }
}

public void Update()
{
    try
    {
        // ..
        IsUpdated = true;
    }
    catch (Exception)
    {
        //...
        IsUpdated = false;
    }
}

Variante 2

public void IrgendwasMachen()
{
    Adresse adresse = new Adresse(new Guid("D3667F33-F0AB-4367-9613-AAF70F9631B3"));
    adresse.Nachname = "Meyer";
    
    if (adresse.Update())
    {
        //..
    }
}

public bool Update()
{
    try
    {
        // ..
       return true;
    }
    catch (Exception)
    {
        //...
        return false;
    }
}

Mir macht Variante 1 den "Objektorientierteren" Eindruck. Weil man ein extra dafür angelegtes Property setzt und nicht den Rückgabetyp der Methode für das Errorhandling "missbraucht". Oder ist das in Ordnung? Wie macht Ihr das?

29.05.2009 - 16:56 Uhr

Ich muss einen Start und Endwert angeben. Deshalb übergebe ich der Next() Methode den Lower- bzw. UpperBound eines arrays.

Was ich aber nicht verstehe: Warum wurde beim Debuggen trotzdem das richtige Ergebnis erstellt? Ist das ein Bug von VS? Wenn ich nun die Lösung so anschaue hätte ich sogar ein Compilerfehler erwartet...

29.05.2009 - 09:14 Uhr

Oh mann.... DANKE!!! Das wars 😄

29.05.2009 - 09:04 Uhr

Es geht um einen Passwortgenerator der pro Runde (wird als Parameter bei GetNewPassword() definiert) 4 Zufallscharacters aussuchen soll. Einen Gross- und einen Kleinbuchstaben, ein Sonderzeichen und eine Zahl. Bei mehreren Runden werden die Blöcke zusammengefügt und ergeben ein Passwort. Demnach ist ein Passwort mit 1 Runde 4 Zeichen lang, 2 Runden sind 8 Zeichen, 3 Runden sind 12 Zeichen usw.

public partial class Test : System.Web.UI.Page
{

    /// <summary>
    /// This Hashtable will contain different <c>char</c> arrays, filled with allowed characters 
    /// </summary>
    private Hashtable charactersHashtable;

    protected void Page_Load(object sender, EventArgs e)
    {
        charactersHashtable = new Hashtable();
        charactersHashtable.Add(0, "!#$%_=+".ToCharArray());
        charactersHashtable.Add(1, "0123456789".ToCharArray());
        charactersHashtable.Add(2, "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray());
        charactersHashtable.Add(3, "abcdefghijklmnopqrstuvwxyz".ToCharArray());
    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        TextBox1.Text = GetNewPassword(3);
    }

    private string GetRandomChar(int hashtableKey)
    {
        char[] c = (char[])charactersHashtable[hashtableKey];

        Random rand = new Random();

        int lower = (int)c.GetLowerBound(0);
        //Response.Write(lower + ",");
        int upper = (int)c.GetUpperBound(0);
        //Response.Write(upper + ",");
            
        int randomCharPosition = rand.Next(lower, upper);
        //Response.Write("[<strong>" + randomCharPosition + "</strong>],");

        return c[randomCharPosition].ToString();
    }

    /// <summary>
    /// Gets the new password.
    /// </summary>
    /// <param name="passwordStrength">Number of rounds, in other words the password strength. Every round creates a block of 4 index keys for the hashtable</param>
    /// <returns>The new generated password</returns>
    public string GetNewPassword(int passwordStrength)
    {

        StringBuilder pwdBuffer = new StringBuilder();
        Queue keysQueue = new Queue();
        Random rand = new Random();

        for (int i = 0; i < passwordStrength; i++)
        {
            // Queue object will be created every round depending on passwordStrength
            Queue rounds = new Queue();

            for (int ii = 0; ii < 4; ii++)
            {
                
                int current = rand.Next(0, 4);
                if (rounds.Contains(current))
                {
                    ii--;
                }
                else
                {
                    rounds.Enqueue(current);
                    keysQueue.Enqueue(current);
                }
                
            }
        }

        int count = keysQueue.Count;

        for (int i = 0; i < count; i++)
        {
            int hashtableKey = Convert.ToInt32(keysQueue.Dequeue());
            string randomChar = GetRandomChar(hashtableKey);

            //**********************
            // Wenn ich hier einen Breakpoint setze und debugge, funktioniert Random tadellos
            //**********************
            pwdBuffer.Append(randomChar);
        }

        //**********************
        // Wenn ich hier einen Breakpoint setze und debugge, generiert Random 4 Zufallszahlen, aber wiederholt diese dann jede Runde.
        // Also wenn ich ein Passwort mit Stärke 3 generiere (siehe Button1_Click()) kriege ich 4 Zufallszahlen, 3 mal wiederholt.
        //**********************
        return pwdBuffer.ToString();

    }

}

Am Schluss von GetNewPassword() steht in Kommentaren, was schief läuft. Es ist echt seltsam. Der einzige Unterschied bei den Breakpoints ist, dass man beim oberen Breakpoint jeden einzelnen Aufruf von GetRandomChar() mitverfolgen kann und beim unteren nicht. Zurückgeben das Ergebnis sollte aber gleich aussehen. Ich bin echt am Ende meines Lateins.

27.05.2009 - 09:56 Uhr

Einen
>
auf die Tabelle legen.

Den Gedanken hatte ich auch. Allerdings bin ich nicht gerade ein Fan von Triggern. Ich mag nicht einmal SP's (auch wenn die ganz schön nützlich sein können). Ich bin der Meinung, das in Datenbanken keine Businesslogik liegen soll.

27.05.2009 - 09:20 Uhr

verwendetes Datenbanksystem: MSSQL 2005

Guten Morgen,

Es ist mir irgendwie kein besserer Titel eingefallen. Es geht um eine Tabelle, in der Adressen gespeichert werden. Sie ist Teil einer Verwaltungssoftware, die ich nicht anpassen kann. Wenn die Tabelle geändert wird, sprich ein oder mehrere Datensätze dazukommen, sollen diese neuen Daten in eine andere Datenbank geschrieben werden. Also quasi eine einseitige Synchronisierung.

Ich habe bereits ein Programm geschrieben, dass diese Aufgabe erfüllt. Bei jeder Ausführung überprüft es die Tabelle ob neue Datensätze vorhanden sind, und schreibt dann ggf. in die zweite Datenbank. Dieses Programm wird einfach jede Minute aufgerufen.

Und genau das stört mich. Ist es nicht möglich, einen neuen Datensatz gleich nach dem dessen Schreibprozess in die Datenbank zu erkennen? Also quasi die Tabelle "abhören" ob was passiert. Was mir so spontan eingefallen ist, dass ich mein Programm abändere und die Logik in eine Endlosschleife packe. Das erscheint mir allerdings als wenig elegant. Ich würde quasi im Millisekundentakt "SELECT COUNT(Flag_NeuerDatensatz) FROM adresses WHERE Flag_NeuerDatensatz = 1" an den SQL Server schicken. Kann das gut sein?

Kennt Ihr irgendwelche Techniken. Oder könnt ihr mir Tips zur Programmierung geben? Das wäre Toll.

Gruss

08.05.2009 - 09:42 Uhr

Hallo epic_fail

Wieso nimmst du nicht einfach das Repeater Control?
Um deine Idee umzusetzen brauchst du sicher mal TextBoxen, diese kannst du sichtbar / unsichtbar schalten.

Den kannnte ich noch gar nicht. Sieht gut aus. Aber schlussendlich ist es ja einfach ein anderer Weg meine Tabelle auszugeben... und mit dem habe ich ja keine Probleme.

Dann musst du den TextBoxen sowie den Buttons IDs vergeben, ansonsten kannst du mit den Controls überhaupt nichts anfangen.
Sagen dir Events was?

Wenn nicht, lies dich da bitte mal ein.

Das mit der ID war ein guter Hinweis. Ich kann jedem LinkButton Control eine ID geben, somit kann ich grundsätzlich kontrollieren welcher LinkButton geklickt wurde. Wie kann ich aber auslesen, welcher es war? Steht das im "object sender" des Events?

06.05.2009 - 17:37 Uhr

Ich möchte auf das vorgefertigte GridView Control verzichten. Mich mag das Teil einfach irgendwie nicht und umgekehrt.

Ich finde aber den Ansatz, die Idee wie der GridView sich präsentiert sehr gut.

Also z.B. dass ich auf einen LinkButton am Ende eines Datensatzes im GridView klicke und dann in der entsprechende Zeile TextBoxen erscheinen, mit denen dann der Datensatz modifiziert werden kann.

Was ich nun nicht begreife ist, wie ich in jeder Zeile den LinkButton richtig verknüpfe. Also ich habe z.B. ein Table Control


List<String> liste = new List<string>();
liste.Add("Eintrag 1");
liste.Add("Eintrag 2");
// usw...

Table table = new Table();

foreach (var eintrag in liste)
{
    TableRow tr = new TableRow();
    
    TableCell tdBeschreibung = new TableCell();
    tdBeschreibung.Text = eintrag;
    tr.Cells.Add(tdBeschreibung);

    TableCell tdEditLinkButton = new TableCell();
    LinkButton lbEdit = new LinkButton();
    //
    // Hier müsste dem LinkButton gesagt werden, dass wenn er geklickt wird, diese Zeile per TextBox editiert werden kann.
    //
    tdEditLinkButton.Controls.Add(lbEdit);

    table.Controls.Add(tr);
}

So sollte das Ergebnis aussehen:

Vorher: http://img2.abload.de/img/06.05bwdl.png
Nachher: http://img2.abload.de/img/06.05dvdy.png

Ich kann ja nicht für jeden LinkButton manuell einen Event erstellen. Es müsste dynamisch geschehen.