Eventhandling und Windows

gthzer

Grünschnabel
Hallo,

hab folgendes Window:

public class Password_dialog : Window
{
public delegate void UpdateHandler(string message);
public event UpdateHandler Update;
Gtk.Entry entry;

public Password_dialog(string title):base(title)
{
Gtk.VBox box = new Gtk.VBox();
entry = new Entry();
Button button = new Button("Passwort senden");
button.Clicked += new EventHandler(button_clicked);
box.Add(entry);
box.Add(button);
this.Add(box);
this.Resize(200,50);
}

protected void button_clicked(object sender, EventArgs args)
{
Update(entry.Text);
this.Destroy();
}
}

}

Und wenn ich dieses Window instanziere, dann habe ich ein merkwürdiges Verhalten, je nach dem von wo aus ich es instanziere. Merkwürdiges Verhalten meint, das im ersten Fall alles korrekt funktioniert und im zweiten das Window nicht korrekt aufgebaut wird. Mal halb, mal nur ein Rahmen. :confused:

Hier funktionierts: (Ist ein Button-Clicked Event aus dem MainWindow)
protected void connect_telnet(object o, EventArgs args)
{
Password_dialog passwd_dialog = new Password_dialog("Nicht Telnet");
passwd_dialog.Update += new Password_dialog.UpdateHandler(password_dialog_update);
passwd_dialog.ShowAll();
}
Hier funktionierts nicht:
Ist ein Event eines externen Assemblies.
protected void data_availabe_telnet(object o, Net.Graphite.Telnet.DataAvailableEventArgs args){
Password_dialog passwd_dialog = new Password_dialog("Nicht Telnet");
passwd_dialog.Update += new Password_dialog.UpdateHandler(password_dialog_update);
passwd_dialog.ShowAll();
}
 
Hallo,

wo hast du denn die Eventhandler liegen? Gleiche Klasse, gleiche Assembly? Von wo aus regestrierst du die Event-Handler?


Gruß Konstantin
 
Hallo,

kann es evtl. daran liegen, dass du den handler (delegate) in der klassendefinition definierst und nicht vor der Klassendefinition?

mfg
wensi
 
Den EventHandler definiere ich erst in der Klasse, da erst zu einem bestimmten Zeitpunkt die Telnet-Verbindung aufgebaut wird.

Muss der Handler denn außerhalb der Klasse definiert werden?

public MainWindow(string title):base(title)
{
// Glade.XML gxml = new Glade.XML(null,"grr.glade.xml", "mainWindow", null);
// gxml.Autoconnect(this);
#region design
Gtk.VBox box = new Gtk.VBox();
Gtk.Toolbar toolbar = new Toolbar();

connect_telnet_button = new ToolButton(null,"Telnet");
connect_telnet_button.Clicked += new EventHandler(connect_telnet);
toolbar.Add(connect_telnet_button);

disconnect_telnet_button = new ToolButton(null,"Disconnect Telnet");
disconnect_telnet_button.Clicked += new EventHandler(disconnect_telnet);
toolbar.Add(disconnect_telnet_button);

box.Add(toolbar);
statusbar1 = new Statusbar();
box.Add(statusbar1);
this.Add(box);
// this.Resize(200, 50);
this.DeleteEvent += on_window_delete_event;
#endregion


t = new TelnetWrapper();
t.DataAvailable += new DataAvailableEventHandler(data_availabe_telnet);
t.Disconnected += new DisconnectedEventHandler(disconnect_telnet);
telnet_connected = false;

}
 
Zuletzt bearbeitet:
Ich glaube was wensi meinte ist, dass du diese Zeile

Code:
public delegate void UpdateHandler(string message);

Außerhalb der Klasse schreiben solltest.


Gruß Konstantin
 
Hallo,

genau das meinte ich. Ich arbeite auch teilweise mit Events die ich selbst deklariert habe. Auch gehe ich damit über interfaces nach aussen. Den Delegaten definiere ich aber immer ausserhalb des infaces oder der Klasse.

mfg
wensi
 
Hallo,

sorry für die lange Wartezeit, aber nun bin ich wieder fit.

Es funktioniert auch mit dem Hinweis noch nicht. Hier mal die vollstädingen Sourcen:
using Glade;
using Gtk;
using Gdk;
using System;
using System.Net.Sockets;
using De.Mud.Telnet;

namespace grr
{
public delegate void UpdateHandler(string message);

public class MainWindow : Gtk.Window
{
[Widget] Gtk.Window mainWindow;
[Widget] Statusbar statusbar1;
[Widget] ToolButton connect_telnet_button;
[Widget] ToolButton disconnect_telnet_button;

private static TelnetWrapper t;
private bool telnet_connected;
private bool need_telnet_session_passwd = false;

public MainWindow(string title):base(title)
{
#region design
Gtk.VBox box = new Gtk.VBox();
Gtk.Toolbar toolbar = new Toolbar();

connect_telnet_button = new ToolButton(null,"Telnet");
connect_telnet_button.Clicked += new EventHandler(connect_telnet);
toolbar.Add(connect_telnet_button);

disconnect_telnet_button = new ToolButton(null,"Disconnect Telnet");
disconnect_telnet_button.Clicked += new EventHandler(disconnect_telnet);
toolbar.Add(disconnect_telnet_button);

box.Add(toolbar);
statusbar1 = new Statusbar();
box.Add(statusbar1);
this.Add(box);
this.DeleteEvent += on_window_delete_event;
#endregion
t = new TelnetWrapper();
t.DataAvailable += new DataAvailableEventHandler(data_availabe_telnet);
t.Disconnected += new DisconnectedEventHandler(disconnect_telnet);
telnet_connected = false;

}

protected void connect_telnet(object o, EventArgs args)
{

#if DEBUG
statusbar1.Push(0,"Connect-Telnet-Button pressed");
#endif
if(!telnet_connected) {
#if DEBUG
System.Console.WriteLine("Telnet-Verbindung wird aufgebaut");
#endif
t.Port = 2600;
t.Hostname = "127.0.0.1";
try {
t.Connect();
System.Console.WriteLine("Verbindung aufgebaut");
telnet_connected = t.Connected;
if(telnet_connected){
// set_button_sensitive(true, true, true, false, true);
t.Receive();
}
}
catch (SocketException socex) {
#if DEBUG
statusbar1.Push(0,"Keine Verbindung zur Telnetschnittstelle möglich");
System.Console.Write(socex.StackTrace.ToString());
#endif
}
}
}

protected void disconnect_telnet(object o, EventArgs args){
#if DEBUG
statusbar1.Push(0,"Disconnect-Telnet-Button pressed");
#endif
if(telnet_connected) {
try {
t.Disconnect();
// //set_button_sensitive(true, false, false, false, false);
} catch (SocketException socex) {
statusbar1.Push(0,"Fehlschlag bei Telnet-Verbindungsabbau");
}
telnet_connected = t.Connected;
}
}

protected void data_availabe_telnet(object o, Net.Graphite.Telnet.DataAvailableEventArgs args){

string temp_args = args.Data;
#if DEBUG
statusbar1.Push(0,temp_args);
#endif
if( temp_args.Contains("ENTER PASSWORD") )
{
statusbar1.Push(0,"Telnet-Passwort wird benötigt");
need_telnet_session_passwd = true;
Password_dialog passwd_dialog = new Password_dialog("Passwort");
passwd_dialog.Update += new Password_dialog.UpdateHandler(password_dialog_update);
passwd_dialog.ShowAll();
}
else
{
System.Console.WriteLine(temp_args+" wird nicht ausgwertet");
}
}

protected void on_activate_info_button(object o, EventArgs args){

}

protected void password_dialog_update(string message){
Console.WriteLine(message);
}

protected void on_window_delete_event(object o, DeleteEventArgs args)
{
Application.Quit();
args.RetVal = true;
}

}
}

using Gtk;
using System;
using Glade;

namespace grr
{

/// <summary>
/// Description of Password_dialog.
/// </summary>
public class Password_dialog : Window
{
public delegate void UpdateHandler(string message);

public event UpdateHandler Update;

Gtk.Entry entry;

public Password_dialog(string title):base(title)
{
Gtk.VBox box = new Gtk.VBox();
entry = new Entry();
Button button = new Button("Passwort senden");
button.Clicked += new EventHandler(button_clicked);
box.Add(entry);
box.Add(button);
this.Add(box);
this.Resize(200,50);
}

protected void button_clicked(object sender, EventArgs args)
{
Update(entry.Text);
this.Destroy();
}
}

}

using System;

namespace grr
{
public class telnet_test
{
static void Main(string[] args)
{
Gtk.Application.Init();
new MainWindow("Telnet Test").ShowAll();
Gtk.Application.Run();
}
}
}

Die verwendete telnet.dll findet ihr hier:
http://dotnettelnet.sourceforge.net/
 
Hallo nochmals,

ich hab das ganze jetzt auch mal mit WinForms probiert und auch dort tritt das selbe Problem auf. Jedoch ist es hier mittels Debugger-Einzelschrittausführung das Problem zu umgehen.

Zusätzlich wird noch die Telnet-Dll benötigt, sie ein Beitrag drüber.

Ich kann mit diesem seltsamen Verhalten nichts anfangen und wäre für Hinweise auf mögliche Ursachen dankbar.

Kann es seien, dass die Methode on_button1_clicked nach dem t.Receive()-Aufruf direkt verlassen wird, weil Daten anliegen. Wenn ich das mit Debug-meldungen versehe und nicht mit Einzelschritt ausführe, dann werden die Meldungen nicht ausgegeben. Bei der Einzelschrittausführung wird das aber wohl gemacht. Wäre da ein Ansatzpunkt?

Form1.cs
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using De.Mud.Telnet;
using System.Net.Sockets;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private static TelnetWrapper t;
        private bool telnet_connected;
        private bool need_telnet_session_passwd = false;

        public Form1()
        {
            InitializeComponent();
            t = new TelnetWrapper();
            t.DataAvailable += new DataAvailableEventHandler(data_availabe_telnet);
            t.Disconnected += new DisconnectedEventHandler(disconnect_telnet);
            telnet_connected = false;
        }

        private void on_button1_clicked(object sender, EventArgs e)
        {
            if (!telnet_connected)
            {
#if DEBUG
                System.Console.WriteLine("Telnet-Verbindung wird aufgebaut");
#endif
                t.Port = 2600;
                t.Hostname = "127.0.0.1";
                try
                {
                    t.Connect();
                    System.Console.WriteLine("Verbindung aufgebaut");
                    telnet_connected = t.Connected;
                    if (telnet_connected)
                    {
                        //		set_button_sensitive(true, true, true, false, true);
                        t.Receive();
                    }
                }
                catch (SocketException socex)
                {
#if DEBUG
                    System.Console.Write(socex.StackTrace.ToString());
#endif
                }
            }
        }

        protected void disconnect_telnet(object o, EventArgs args)
        {

           /* if (telnet_connected)
            {
                try
                {
                    t.Disconnect();
                    telnet_connected = false;
                }
                catch (SocketException socex)
                {
               //     statusbar1.Push(0, "Fehlschlag bei Telnet-Verbindungsabbau");
                }
            }
       */ }

        /*		private void password(){
                    Password_dialog passwd_dialog = new Password_dialog("Passwort");
                    passwd_dialog.Update += new Password_dialog.UpdateHandler(password_dialog_update);
                    passwd_dialog.ShowAll();
                }
        */
        protected void data_availabe_telnet(object o, Net.Graphite.Telnet.DataAvailableEventArgs args)
        {

            string temp_args = args.Data;
            if (temp_args.Contains("ENTER PASSWORD"))
            {
                need_telnet_session_passwd = true;
                //			trayIcon.Blinking = true;
                Form2 passwd_dialog = new Form2();
                passwd_dialog.Update += new Form2.UpdateHandler(password_dialog_update);
                passwd_dialog.Show();
              //  passwd_dialog.ShowAll();
            }
            else
            {
                System.Console.WriteLine(temp_args + " wird nicht ausgwertet");
            }
        }

        protected void password_dialog_update(string message)
        {
            textBox1.Text = message;
        }

        private void disconnect_clicked(object sender, EventArgs e)
        {
            telnet_connected = false;
            t.Disconnect();
        }
    }
}

Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using De.Mud.Telnet;
using System.Net.Sockets;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private static TelnetWrapper t;
        private bool telnet_connected;
        private bool need_telnet_session_passwd = false;

        public Form1()
        {
            InitializeComponent();
            t = new TelnetWrapper();
            t.DataAvailable += new DataAvailableEventHandler(data_availabe_telnet);
            t.Disconnected += new DisconnectedEventHandler(disconnect_telnet);
            telnet_connected = false;
        }

        private void on_button1_clicked(object sender, EventArgs e)
        {
            if (!telnet_connected)
            {
#if DEBUG
                System.Console.WriteLine("Telnet-Verbindung wird aufgebaut");
#endif
                t.Port = 2600;
                t.Hostname = "127.0.0.1";
                try
                {
                    t.Connect();
                    System.Console.WriteLine("Verbindung aufgebaut");
                    telnet_connected = t.Connected;
                    if (telnet_connected)
                    {
                        //		set_button_sensitive(true, true, true, false, true);
                        t.Receive();
                    }
                }
                catch (SocketException socex)
                {
#if DEBUG
                    System.Console.Write(socex.StackTrace.ToString());
#endif
                }
            }
        }

        protected void disconnect_telnet(object o, EventArgs args)
        {

           /* if (telnet_connected)
            {
                try
                {
                    t.Disconnect();
                    telnet_connected = false;
                }
                catch (SocketException socex)
                {
               //     statusbar1.Push(0, "Fehlschlag bei Telnet-Verbindungsabbau");
                }
            }
       */ }

        /*		private void password(){
                    Password_dialog passwd_dialog = new Password_dialog("Passwort");
                    passwd_dialog.Update += new Password_dialog.UpdateHandler(password_dialog_update);
                    passwd_dialog.ShowAll();
                }
        */
        protected void data_availabe_telnet(object o, Net.Graphite.Telnet.DataAvailableEventArgs args)
        {

            string temp_args = args.Data;
            if (temp_args.Contains("ENTER PASSWORD"))
            {
                need_telnet_session_passwd = true;
                //			trayIcon.Blinking = true;
                Form2 passwd_dialog = new Form2();
                passwd_dialog.Update += new Form2.UpdateHandler(password_dialog_update);
                passwd_dialog.Show();
              //  passwd_dialog.ShowAll();
            }
            else
            {
                System.Console.WriteLine(temp_args + " wird nicht ausgwertet");
            }
        }

        protected void password_dialog_update(string message)
        {
            textBox1.Text = message;
        }

        private void disconnect_clicked(object sender, EventArgs e)
        {
            telnet_connected = false;
            t.Disconnect();
        }
    }
}


Form2.cs
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form2 : Form
    {
        public delegate void UpdateHandler(string message);
        public event UpdateHandler Update;

        public Form2()
        {
            InitializeComponent();
        }

        private void on_button_clicked(object sender, EventArgs e)
        {
            Update(textBox1.Text);
          //  this.Destroy();
            this.Close();
        }
    }
}

Code:
namespace WindowsFormsApplication1
{
    partial class Form2
    {
        /// <summary>
        /// Erforderliche Designervariable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Verwendete Ressourcen bereinigen.
        /// </summary>
        /// <param name="disposing">True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Vom Windows Form-Designer generierter Code

        /// <summary>
        /// Erforderliche Methode für die Designerunterstützung.
        /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
        /// </summary>
        private void InitializeComponent()
        {
            this.button1 = new System.Windows.Forms.Button();
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            // 
            // button1
            // 
            this.button1.Location = new System.Drawing.Point(205, 209);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(75, 23);
            this.button1.TabIndex = 0;
            this.button1.Text = "button1";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.on_button_clicked);
            // 
            // textBox1
            // 
            this.textBox1.Location = new System.Drawing.Point(124, 106);
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(100, 20);
            this.textBox1.TabIndex = 1;
            // 
            // Form2
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(292, 266);
            this.Controls.Add(this.textBox1);
            this.Controls.Add(this.button1);
            this.Name = "Form2";
            this.Text = "Form2";
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.TextBox textBox1;
    }
}
 
Hallo,

wenns beim debuggen (mit einzelschritten) funktioniert bin ich leider überfragt. Kann es sein, dass du den Delegaten mehrmals definierst? Ich definier mir den Delegaten immer genau einmal und benutz dann auch nur den. Ich dachte immer ich brauch nur 2 delegaten wenn ich mit Multithreading arbeite, damit ich mit Invoke das ganze wieder syncronisieren kann.

Sorry, wenn ich dir keine wirkliche Hilfe war.

mfg
wensi
 
@wensi: Hast du dir denn das WinForms-Beispiel mal angeschaut? Vielleicht läuft es ja einfach nur auf meinem Rechner nicht, weil ich was auch immer installiert habe, was verhindert, dass es läuft.
 

Neue Beiträge

Zurück