Autor Beitrag
Glowhollow
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 77



BeitragVerfasst: Di 23.04.19 10:27 
Guten Morgen,

ich hoffe ihr hattet ein schönes Ostern.

Momentan beschäftige ich mich mit Custom Events, bin da aber noch nicht ganz durchgestiegen.

Ich zeig euch mal was ich bisher habe.

Im Prinzip möchte ich einen Event abfeuern, der je nach übergebenen Wert (in dem Fall ein Bool) eine Form sichtbar, bzw. unsichtbar macht.

Ich habe im Controller folgendes:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
 public delegate void StatusUpdateHandler(object sender, ProgressEventArgs e);
        public event StatusUpdateHandler SplashShowStatus;



        public SplashController(ISplashScreenView view)
        {
            _view = view;
            view.SetController(this);
        }

        private void _SplashShowStatus(bool status)
        {
            if (SplashShowStatus == nullreturn;
            ProgressEventArgs args = new ProgressEventArgs(status);
            SplashShowStatus(this, args);
        }

        public class ProgressEventArgs : EventArgs
        {
            public bool Status { get; private set; }
            public ProgressEventArgs(bool status)
            {
                Status = status;
            }
        }


und in der Form

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
SplashController _controller;
   
        public Splashscreen()
        {
            InitializeComponent();
            _controller.SplashShowStatus += new SplashController.StatusUpdateHandler(UpdateStatus);

        }

        public bool ViewStatus = false;

        private void UpdateStatus(object sender, ProgressEventArgs e)
        {
            SetStatus(ViewStatus);
        }

       

        private void SetStatus(bool value)
        {
            if(value == true)
            {
                this.Visible = true;
                this.ViewStatus = true;
            }
            else if(value == false)
            {
                this.Visible = false;
                this.ViewStatus = false;
            }
        }


Allerdings wird hier bemängelt, das keine Überladung für "UpdateStatus" stimmt mit dem Delegaten "SplashController.StatusUpdateHandler" überein.

Im Prinzip möchte ich eine Event feuern, das mit einem Bool versehen ist, worauf dann die Form reagiert und sich selbständig unsichtbar bzw. sichtbar schaltet.

Leider komme ich mit der kryptischen Aussage nicht ganz zurecht und weiß jetzt nicht was von mir verlang wird.

Mag mich hier jemand erleuchten ?

Vielen Dank !

Moderiert von user profile iconChristian S.: Code- durch C#-Tags ersetzt
Glowhollow Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 77



BeitragVerfasst: Di 23.04.19 11:23 
Ok, hab herausgefunden woran es lag.

erstens. der SetStatus teil war falsch. Dort habe ich jetzt SetStatus(e.Status).

zudem hatte ich noch einen möglichen unsafe thread in der _SplashShowStatus den ich mit SplashSowStatus?.Invoke(thisnew ProgressEventArgs(status)) korrigieren können.

Jetzt ist es aber so, das ich verschiedene Events habe, die listener setzen und so ist kein Ding. Jedoch müßte ich den ProgressEventArgs erweitern (in dem Falle ists ja nur 1 Event).

Was mache ich aber, wenn ich 10 unterschiedliche Events habe ? Wie kapsele ich das ?

Moderiert von user profile iconTh69: C#-Tags hinzugefügt
Glowhollow Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 77



BeitragVerfasst: Di 23.04.19 15:44 
Gut, konnte meine Problem soweit beheben, das Event wird schon geworfen. Jetzt ist mir hier allerdings einiges unklar.

Im MainFormController
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
public delegate void StatusUpdateHandler(object sender, ProgressEventArgs e);
public event StatusUpdateHandler UpdateTSSLMainConnection;
public void _UpdateTSSLMainConnection(string value)
{
    UpdateTSSLMainConnection?.Invoke(thisnew ProgressEventArgs(value));
}

public class ProgressEventArgs:EventArgs
{
    public string Status { get; private set; }
    public ProgressEventArgs(string value)
    {
        Status = value;
    }
}


in der dazugehörigen MainForm
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
private void UpdateTSSLMainConnection(object sender, MainFormController.ProgressEventArgs e)
{
    SetText(e.Status);
}

private void SetText(string value)
{
    this.TSSLmainconnection.Text = value;
}

Wiegesagt, das Event wird geworfen (laut debugger erreicht er den Code, Parameter sind soweit gut, so wie es sein soll), aber ich erwarte eigentlich, das er in der Mainform, die werte ändert. Da kommt er aber nicht hin. Was muß ich tun, das in der Mainform, der Code ausgeführt wird. Was hab ich übersehen ?

Moderiert von user profile iconTh69: Code- durch C#-Tags ersetzt
Chiyoko
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 298
Erhaltene Danke: 8

Win 98, Win Xp, Win 10
C# (VS 2017)
BeitragVerfasst: Di 23.04.19 16:53 
Erstmal ein par formale Dinge:

1) Bitte benutze cs-Tags , nicht code-Tags. Th69 korrigiert das ständig aber du merkst es nicht.
2) Halte dich an die Microsoftkonventionen, macht den Code viel lesbarer.
3) Ab C# 7.2 gibt es einen tenären Operator "?:". Damit kannst du if/else Abfragen abkürzen. Mag nicht jeder, kann aber die Lesbarkeit erhöhen. Oder du negierst bei boolischen Werten einfach die Abfrage.
In deinem Fall geht auch:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
private void SetStatus(bool value)
{
   this.Visible = value;
   this.ViewStatus = value;
}


Zur Lösungsfindung:
Vermutlich setzt du die Property Visible viel zu spät oder an der falschen Stelle. Du solltest prüfen, ob bereits das Handle existiert.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4014
Erhaltene Danke: 826

Win7
C++, C# (VS 2015/17)
BeitragVerfasst: Di 23.04.19 16:53 
Hast du das Event denn in der MainForm abonniert? [Auch wenn ich immer noch meine, daß der Controller zwar die MainForm kennen darf, aber eben nicht umgekehrt!]

PS:
Für die Delegates gibt es schon generische Typen im .NET Framework, so daß du die ersten beiden Zeilen durch eine Zeile ersetzen kannst:
ausblenden C#-Quelltext
1:
public event EventHandler<ProgressEventArgs> SplashShowStatus;					

Desweiteren gibt es noch die generischen Delegates Action<T, ...>, Func<R, T, ...> sowie Predicate<T, ...>, s. z.B. Func, Action and Predicate in C# With Example und C# Generic Delegates Func, Action, and Predicate.

PPS: Bitte benutze die C#-Tags (nicht nur die Code-Tags)!
Glowhollow Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 77



BeitragVerfasst: Di 23.04.19 17:44 
@Chiyoko

das mit dem visible hab ich hinbekommen. das läuft jetzt.


Hallo Th69 !

Danke das du dich meiner erbarmst :).

Ja hab ich. Da ich anfangs noch die ganzen Scopes setzen mußte, abboniere ich den Handler über das MainProgram, über einen Aufruf à la AddEventsToMainForm().

dort steht drin...

ausblenden C#-Quelltext
1:
2:
3:
4:
 public void AddEventsToMainForm()
{
    _controller.UpdateTSSLMainConnection += new MainFormController.StatusUpdateHandler(UpdateTSSLMainConnection);
}

Der Event wird ja auch geworfen in der dbcon, jedoch ist die referenz auf den Listener immer noch null.

Edit... jetzt hab ich das mit dem cs tag gefunden, danke !
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4014
Erhaltene Danke: 826

Win7
C++, C# (VS 2015/17)
BeitragVerfasst: Di 23.04.19 18:04 
Dann hast du verschiedene UpdateTSSLMainConnection-Methoden (drücke mal "Gehe zu Definition (F12)")...
Glowhollow Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 77



BeitragVerfasst: Mi 24.04.19 09:53 
Ach, habs herausgefunden, ich droppe den event, obwohl er noch garnicht registriert ist, deswegen läuft das auf null hinaus. Hab den code angepasst.

Gut, Wie ist das mit mehreren Events, die auf EventArgs reagieren ... Ich meine, ich will diese ganze Form kommunikationen über events laufen lassen. Bei so vielen Events, was ist da die beste Herangehensweise ?

[Edit]
Habe etwas über EventList gefunden, allerdings sind die Beispiele dich bis jetzt gefunden habe eher meh...

Kann mir hier jemand was zu sagen ? Z.bsp. 3 Unterschiedliche Events, die alle unterschiedliche sachen ändern ?
Chiyoko
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 298
Erhaltene Danke: 8

Win 98, Win Xp, Win 10
C# (VS 2017)
BeitragVerfasst: Mi 24.04.19 11:18 
Wenn du mehrere Events hast, die alle das gleiche (?) machen, bietet sich eine EventHandlerList an.
Ist ja letztlich auch nur ne Art erweitertes Dictionary.