Autor Beitrag
Talemantros
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 444
Erhaltene Danke: 2

Win7 Proff 64bit
C# (VS2013)
BeitragVerfasst: Mo 28.12.15 17:34 
Hallo zusammen,
ich habe da mal wieder ein kleines Problem, welches ich leider nicht gelöst bekomme.
Wo ich noch Forms benutzt habe um Steuerelemente anzuzeigen war es kein Problem mit

ausblenden C#-Quelltext
1:
this.close();					


dieses zu schließen.

Nun zeige ich ja die Steuerelemte in einem UserControl an, welches geladen wird.
Wie kann ich einem Button nun sagen, dass er beim Klick das Form unter dem UserControl schließen soll?

Danke.

Viele Grüße
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Di 29.12.15 15:09 
Da stellt sich die Frage wieso der Button auf einem UserControl liegt. Ein Button dessen Aufgabe das schließen der Form ist auf einem UserControl zu haben richt etwas nach Designfehler.

Wenn der Button da aus irgendeinem mir nicht ersichtlichen Grund hin muss dann würde ich vom UserControl ein entsprechendes Event veröffentlichen damit ich den passenden Code dann auf der Form ausführen kann. Also den Click Event des Button den entsprechenden Event des UserControls ausführen lassen damit dort das passende auf der Form ausgeführt werden kann.
Talemantros Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 444
Erhaltene Danke: 2

Win7 Proff 64bit
C# (VS2013)
BeitragVerfasst: Mi 30.12.15 17:09 
Hey,
also aus meiner Sicht gab es dazu keinen Grund.
Ich dachte, dass wäre so, dass man auf der Form nichts mehr hat, da das UserControl ja mit Dock.Fill geladen wird und der Button dann nicht sichtbar ist?
Daher implizierte ich, dass auch der Schließen Button da hin gehört.

Gruß

EDIT:
bzw. wenn die Form sich selber schließen soll, nach bestimmten Aktivitäten in der UserControl müsste ich vermutlich wieder mit Events arbeiten?
C#
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 561
Erhaltene Danke: 65

Windows 10, Kubuntu, Android
Visual Studio 2017, C#, C++/CLI, C++/CX, C++, F#, R, Python
BeitragVerfasst: Mi 30.12.15 17:56 
Tach,

quick and dirty kannst du das Fenster so schließen:
ausblenden C#-Quelltext
1:
((Form)this.Parent).Close();					


Aber wie Ralf bereits geschrieben hat, sollte ein UserControl nicht die Form manipulieren.

_________________
Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mi 30.12.15 18:57 
Zitat:
Ich dachte, dass wäre so, dass man auf der Form nichts mehr hat, da das UserControl ja mit Dock.Fill geladen wird und der Button dann nicht sichtbar ist?


Du mußt das UserControl nicht direkt auf die Form werfen. Zum Beispiel wäre es ein leichtes die Form mit 2 Panel zu strukturieren. Ein Panel für die Buttons zum steuern der Form (mit Dock.Bottom) und ein 2.tes (mit Dock.Fill) um darauf dann wieder verschiedene UserControl platzieren zu können. Wenn du dann Dock.Fill des UserControls setzt füllt es ja nur die Fläche seines Parents also des Panels.

@C# Das der Parent eine Form ist wäre eher Zufall. Auf jedenfall wäre solcher Code unglücklich weil man das UserControl in seiner Nutzung soweit einschränkt das es nur funktioniert wenn man es direkt auf eine Form wirft. Quick and Dirty ist da schon mehr als eine Untertreibung ;)

Zitat:
bzw. wenn die Form sich selber schließen soll, nach bestimmten Aktivitäten in der UserControl müsste ich vermutlich wieder mit Events arbeiten?


Müssen musst du nicht. Ich würde es aber höchstwahrscheinlich als den richtigen Weg bezeichnen.
C#
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 561
Erhaltene Danke: 65

Windows 10, Kubuntu, Android
Visual Studio 2017, C#, C++/CLI, C++/CX, C++, F#, R, Python
BeitragVerfasst: Mi 30.12.15 21:17 
@Ralf dann macht man einfach eine hierarchische Suche ala:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
Control c = this.Parent;
while (c != null
{
  Form f = c as Form;
  if (f != null)
  {
    f.Close();
    break;
  }
  c = c.Parent;
}

:dance:

_________________
Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler
Talemantros Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 444
Erhaltene Danke: 2

Win7 Proff 64bit
C# (VS2013)
BeitragVerfasst: Mi 30.12.15 21:53 
Schon mal danke euch beiden
Bisher habe ich erst einmal ein Event geschrieben und das ist ewig her

Da ich dies sicher nich öfter brauche würde ich mir dies gern genauer anschauen.
Auch die Idee mit den Panels werde ich aufnehmen.

Würdet ihr mir Hilfestellung geben mit dem Event?
Ich wüsste gerade nicht wie ich anfangen sollte.

Versuche mal das alte Event irgendwie zu nutzen.
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mi 30.12.15 22:34 
user profile iconC# hat folgendes geschrieben Zum zitierten Posting springen:

:dance:


Gratuliere du hast ungefähr FindForm nachimplementiert ;)
Talemantros Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 444
Erhaltene Danke: 2

Win7 Proff 64bit
C# (VS2013)
BeitragVerfasst: Mi 30.12.15 23:49 
Leider finde ich keinen Anfang
Beim letzten hatte ich TextEventArgs verwendet, gibt's da jetzt ButtonEventArgs oder woher weiß ich wie ich da starte ?
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 31.12.15 00:11 
Zitat:
Leider finde ich keinen Anfang


Für was? Wenn du keine speziellen EventArgs brauchst nimm einfach die EventArgs Klasse.
C#
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 561
Erhaltene Danke: 65

Windows 10, Kubuntu, Android
Visual Studio 2017, C#, C++/CLI, C++/CX, C++, F#, R, Python
BeitragVerfasst: Do 31.12.15 02:37 
Also ich würde ein eigenes event für das UserControl erstellen. So etwas wie
public event EventHandler<DeineEventArgs> OnCloseRequest;


@Ralf
Homer-nein
Einloggen, um Attachments anzusehen!
_________________
Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler
Talemantros Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 444
Erhaltene Danke: 2

Win7 Proff 64bit
C# (VS2013)
BeitragVerfasst: Do 31.12.15 11:47 
Guten Morgen,
es tut mir sehr leid, aber leider komme ich nicht klar.
Ich habe versucht, das einzige Event in meinem Tool noch mal zu verstehen und selbst das gelingt mir gerade nicht mehr.

Wenn ich im UserControl anfange:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
        public event EventHandler<ButtonEventArgs> CloseRequest;

        protected virtual void OnCloseRequest(ButtonEventArgs e)
        {
            EventHandler<ButtonEventArgs> ev = CloseRequest;
            if (ev != null)
                ev(this, e);
        }


Vorausgesetzt, dass oben stehende würde stimmen müsste ich nach abarbeiten des UserControls, wenn es sich schließen soll dies aufrufen
ausblenden C#-Quelltext
1:
OnCloseRequest();					


Wie bzw. was muss ich den jetzt in der Form machen, damit diese weiß, wie sie das Event fängt und dann eine Aktion ausführt.

Danke

Gruß
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Do 31.12.15 12:34 
So wie bei anderen Ereignisse aus: in deiner Form-Klasse abonnierst du das Event und in der aufgerufenen Eventmethode führst du dann die Aktion aus.

Auch bzgl. deiner anderen Frage Methode einer anderen Form kann ich dich nur (wieder) auf meinen Artikel Kommunikation von 2 Forms hinweisen.

Du scheinst Ereignisse noch nicht (richtig) verinnerlicht zu haben. Der Sinn besteht ja darin, daß die untergeordnete Klasse nicht die übergeordnete (andere) Klasse kennen muß, sondern einfach nur signalisiert: "hier ist etwas passiert und in den EventArgs stehen weitere Infos dazu". Was die andere Klasse (bzw. anderen Klassen) dann damit macht, ist der Klasse, welche das Ereignis wirft, dann völlig egal.
Erst im Gesamtzusammenhang ergibt sich dann der komplette Programmablauf (die Ereignisse und Methodenaufrufe anderer Klassen sind dann die Bindeglieder).
Talemantros Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 444
Erhaltene Danke: 2

Win7 Proff 64bit
C# (VS2013)
BeitragVerfasst: Do 31.12.15 14:55 
Danke noch mal für die ausführliche Erläuterung.
Ich habe dies tatsächlich noch nicht richtig begriffen :-(

Ich bleib dran und versuche dass hier morgen mal anzugehen.

Edit:
Ich habe jetzt folgendes und es funktioniert.
Würde euch mal bitten zu gucken, ob es so gelassen werden kann.

Im UserControl habe ich folgendes deklariert
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
        public event EventHandler<ButtonEventArgs> CloseRequest;

        protected virtual void OnCloseRequest(ButtonEventArgs e)
        {
            EventHandler<ButtonEventArgs> ev = CloseRequest;
            if (ev != null)
                ev(this, e);
        }

        public class ButtonEventArgs : EventArgs
        {
            public ButtonEventArgs()
            {
            }
        }


Und rufe es wie folgt auf

ausblenden C#-Quelltext
1:
                OnCloseRequest(new ButtonEventArgs());					


Im Form selber habe ich

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
                    BarcodeNeuUserControl controlNeu = new BarcodeNeuUserControl(employee);
                    controlNeu.BarcodeText = barcodeText;
                    controlNeu.CloseRequest += CloseForm; // Das hier ist neu dazugekommen
                    controlNeu.Dock = DockStyle.Fill;
                    Controls.Add(controlNeu);


Und hiermit ist es abonniert
ausblenden C#-Quelltext
1:
2:
3:
4:
        private void CloseForm(object sender, BarcodeNeuUserControl.ButtonEventArgs e)
        {
            this.Close();
        }


Danke fürs prüfen und im Allgemeinen für die Hilfe

Gruß
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 31.12.15 15:27 
Sieht korrekt aus.

Der Sinn von ButtonEventArgs ergibt sich mir nicht (und was soll Button im Namen? Wenn schon CloseRequest dann würde ich das eher auch CloseRequestEventArgs nennen). Warum benutzt du nicht einfach EventArgs? Eine eigene Klasse brauchst du erst wenn du mit denn EventArgs auch Daten zum Auswerten im Event transportieren willst.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Fr 01.01.16 17:24 
Hallo Talemantros,

zuerst einmal "Frohes Neues Jahr".

Genauso meinte ich es (aber den Anmerkungen von Ralf stimme ich auch zu ;- )
Wichtig ist aber zu wissen und zu verstehen, wie man eigene EventArgs benutzt, wenn man sie denn wirklich braucht.
C#
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 561
Erhaltene Danke: 65

Windows 10, Kubuntu, Android
Visual Studio 2017, C#, C++/CLI, C++/CX, C++, F#, R, Python
BeitragVerfasst: Fr 01.01.16 17:50 
Ein frohes Neues auch von mir.

Eigene EventArgs machen nur Sinn, wenn du zusätzliche Informationen bereitstellen willst. Angenommen du willst den Grund weitergeben, warum die Form geschlossen werden soll, dann machst du dir ein Enum mit den möglichen Gründen, z.B.:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
enum CloseReasons
{
    None,
    UserForced,
    ControlNeedsReload,
}


Um diesen Grund jetzt and deine subs weiterzuleiten, musst du eine eigene EventArgs-Klasse erstellen:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
public class CloseEventArgs : EventArgs
{
    public CloseReason Reason {get; private set;}
    
    public CloseEventArgs(CloseReason reason)
    {
        Reason = reason;
    }
}


Dann wird dein Event so aussehen:
ausblenden C#-Quelltext
1:
public event EventHandler<CoseEventArgs> CloseRequest;					


Deine Helfermethode sieht dann so aus:
ausblenden C#-Quelltext
1:
2:
3:
4:
protected virtual void OnCloseRequest(CloseEventArgs e)
{
    if (CloseRequest != null) CloseRequest(this, e);
}


In den subs kannst du dann die Infos verwenden:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
private void CloseForm(object sender, CloseEventArgs e)
{
    if (e.Reason != CloseReason.None) this.Close();
    else MessageBox.Show("No given close reason.");
}




Wenn du keine zusätzlichen Infos weitergeben möchtest bei deinen Events, reicht die EventArgs-Klasse. Dein event sieht dann so aus:
ausblenden C#-Quelltext
1:
public event EventHandler<EventArgs> CloseRequest;					

oder etwas kürzer
ausblenden C#-Quelltext
1:
public event EventHandler CloseRequest;					


Auslösen tust du das Event dann mit:
ausblenden C#-Quelltext
1:
OnCloseRequest(new EventArgs())					

oder mit
ausblenden C#-Quelltext
1:
OnCloseRequest(EventArgs.Empty)					

_________________
Der längste Typ-Name im .NET-Framework ist: ListViewVirtualItemsSelectionRangeChangedEventHandler
Talemantros Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 444
Erhaltene Danke: 2

Win7 Proff 64bit
C# (VS2013)
BeitragVerfasst: Sa 02.01.16 14:03 
Hallo zusammen und auch von mir ein "Frohes neues Jahr"
Danke für die weiteren Erläuterungen.
Ich habe diese eben noch mal bei mir umgesetzt.

Daraus ergibt sich jetzt noch eine Frage:
Im Moment abonniert ja die Form das Event, des UserControls.
Die Form selber ist eine Form die von der Hauptanwendung aus gestartet wurde.

Wenn ich jetzt wollte, dass das Hauptfenster der Anwendung dies abonniert wie wäre das dann?
Müsste dann die Form, die es aktuell abonniert wieder ein Event auslösen, welches von der Hauptanwendung gefangen wird?

Zum Beispiel bei einem MouseOver über ein Steuerelement soll in der Statusleiste der Hauptanwendung ein InfoText dazu stehen?

Vielen Dank

Gruß
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Sa 02.01.16 15:06 
Ja und ein bisschen nein ;)

Ja wenn du tatsächlich die Anforderung hast eine reine Userinteraktion einer Form an eine andere weiterzuleiten wird meist ein Event der günstigste Weg sein.
Aber diese Art der Anforderung erscheint mir eher fragwürdig. Wenn sich Formen etwas teilen sind es eher Daten und in dem Fall wäre es eher so das das Model Events wirft das von den betroffenen Formen gefangen wird, die Formen würden dann untereinander nicht direkt kommunizieren. Unabhängigkeit der Einzelteile ist ein hohes gut in einer Anwendung gerade der UI daher ist es üblich das die UI Bestandteile untereinander so wenig wie möglich (eben nur da wo absolut nötig) miteinander direkt kommunizieren.

In deinem Beispiel mit dem MouseOver wäre wohl der Weg über eine Event ok. Wenn das aber ein übliches Problem dieser Anwendung ist (Dinge die irgendwo passieren sollen auf der Mainform visualisiert werden) dann würde ich über ein richtiges Anwendungspattern wie zum Beispiel einen Message Broker nachdenken. Also einen Service an den alle Formen/Controls einer Anwendung Nachrichten senden können, der Message Broker würde dann die Informationen aller Formen sammeln (loggen, priorisieren oder was auch immer sonst noch nötig wäre) und diese dann an die Mainform zu Darstellung weitergeben.
Talemantros Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 444
Erhaltene Danke: 2

Win7 Proff 64bit
C# (VS2013)
BeitragVerfasst: Sa 02.01.16 23:17 
Hallo Ralf,
War ja wieder klar , dass es nicht so einfach ist. :-)
Kennst mich bestimmt schon gut genug um zu wissen, dass ich mich zum weiter entwickeln eher für den Message Broker interessiere.

Ich versuche da im Netz mal was zu finden.
Mache den Eintrag hier erst mal zu um keine Verwirrung zu stiften und dann zum Message Broker einen neuen auf, wenn ich es mal alleine versucht habe.

Gruß