[c# winforms] eventhandling buttons: aparte actions classes?

Pagina: 1
Acties:

  • JeroenTheStig
  • Registratie: Mei 2000
  • Laatst online: 23:47
Na 5 jaar java heb ik de overstap gemaakt op c#. Op dit moment ben ik nog een c#-n00b, dus ik heb een paar boeken besteld die hopelijk deze week worden bezorgd. In Java heb ik een tijdje geleden geleerd hoe je je eigen actions kunt bouwen doormiddel van de abstracte klasse 'AbstractAction'. Voordelen hiervan zijn onder andere een hele nette codeopbouw en het meegeven van parameters (heel handig bij onder andere het aanroepen van je help-frame met verschillende topics). Hieronder even een voorbeeldje:

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Blaat {
  public void build() {
    ...
    JButton helpButton = new JButton(new HelpAction("applicatie info"));
    ...
  }
}

public class HelpAction extends AbstractAction {
  public HelpAction(String helpTopic) {
    ..
    ..
 }
}


In C# ben ik al een tijdje op zoek naar een oplossing hoe ik op ongeveer dezelfde manier eigen actions kan bouwen. Borland C#builder maakt er gelukkig niet zo'n zootje van als in JBuilder, maar toch ben ik nog steeds niet tevreden. Mijn classes worden enorm groot, en het ziet er gewoon niet mooi uit. Bij het initialiseren van een button is het mogelijk om als parameter een reference 'EventHandler' mee te geven, waar een methodenaam uit de klasse waar de button is geinitialiseerd moet worden meegegeven. Je krijgt dus dit soort code:

C#:
1
2
3
4
5
6
7
8
9
10
11
public class Blaat {
  public void initComponents() {
    MenuItem menuFileItem1 = new MenuItem("&Open");
    menuFileItem1.Click += new EventHandler(menuFileItemOpen_Click);
    menuFile.MenuItems.Add(menuFileItem1);
  }

  private void menuFileItemOpen_Click(object sender, System.EventArgs e) {
    System.Console.WriteLine("Bla");
  }
}


Op den duur wordt dit natuurlijk een klasse van belachelijk veel regels, wat ik best onoverzichtelijk vind. Ook zou het handig zijn om direct bij het initialiseren van een button een extra parameter mee te geven van bijvoorbeeld de naam van een helptopic die moet worden laten zien in een helpframe.

Ik heb allerlei websites afgestruind, maar heb nog niks interessants gevonden. Events, References, allemaal leuke tutorials, maar nog nergens iets gevonden wat mij kan helpen. Is er iemand die mij wel verder op weg kan helpen?

[ Voor 3% gewijzigd door JeroenTheStig op 22-06-2004 09:38 ]


  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 21-05 14:59

pjvandesande

GC.Collect(head);

Dit scheelt 1 regel code. Het is niet mogelijk in C# zover ik weet. Maar ik zie ook niet echt het probleem.

Je moet het event toch wire'n aan een method. :?

  • JeroenTheStig
  • Registratie: Mei 2000
  • Laatst online: 23:47
questa schreef op 22 juni 2004 @ 10:36:
Dit scheelt 1 regel code. Het is niet mogelijk in C# zover ik weet. Maar ik zie ook niet echt het probleem.

Je moet het event toch wire'n aan een method. :?
Naar mijn mening scheelt het niet alleen 1 regel code, maar scheelt het vooral een hoop ellende qua overzichtelijkheid. Als ik mijn knoppen initialiseer, wil ik direct zien wat die knop doet en welke parameters hier in worden gestopt. Ik zou het erg fijn vinden om alle acties apart te houden zodat ik die ergens anders in het project ook weer kan gebruiken.

  • Infinitive
  • Registratie: Maart 2001
  • Laatst online: 25-09-2023
Ik zie het verschil niet echt tussen de actions in java en events in .net hoor. Je bent niet verplicht om de eventhandler in dezelfde klasse te plaatsen als het knopje of het menu-item. Dat je daardoor een regeltje of vier code iets anders moet schrijven, tja, daar valt niets tegen te doen.

putStr $ map (x -> chr $ round $ 21/2 * x^3 - 92 * x^2 + 503/2 * x - 105) [1..4]


  • JeroenTheStig
  • Registratie: Mei 2000
  • Laatst online: 23:47
Infinitive schreef op 22 juni 2004 @ 10:40:
Ik zie het verschil niet echt tussen de actions in java en events in .net hoor. Je bent niet verplicht om de eventhandler in dezelfde klasse te plaatsen als het knopje of het menu-item. Dat je daardoor een regeltje of vier code iets anders moet schrijven, tja, daar valt niets tegen te doen.
Ik kan de eventhandler dus in een andere class plaatsen? Ik zou dus alle eventhandlers in een aparte namespace zetten zodat ik ze ook ergens anders snel kan gebruiken?

Over de parameters die ik mee wil geven heb ik nog even een vraag: Stel ik heb een helpfunctie die een aantal topics kan laten weergeven. (je kent het wel als de helpfunctie van bijvoorbeeld microsoft word)
Nu heb ik kris kras door mijn project enkele helpbuttons die elk een eigen helptopic moet laten zien. In Java kon ik dat dus heel mooi doen op de volgende manier:

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
...
  {
    ...
    JButton helpButton = new JButton(new HelpAction("applicatie info"));
    ...
  {
...

// andere class
...
  {
     ...
     JButton helpButton = new JButton(new HelpAction("edit info"));
     ...
  }
...


Nou ja, je snapt mijn idee wel. Je bouwt je panelen op, je ziet direct waar een knop voor dient, en je kunt dezelfde HelpAction meerdere keren gebruiken (in welke class dan ook), terwijl hij telkens een zelf gedefinieerde helptopic laat zien.

Zoiets bestaat dus niet voor c#?

  • Infinitive
  • Registratie: Maart 2001
  • Laatst online: 25-09-2023
Boktor schreef op 22 juni 2004 @ 10:57:
(...)
Zoiets bestaat dus niet voor c#?
Met C# zou je het volgende kunnen doen:

C#:
1
2
3
4
5
6
7
8
9
class HelpAction
{
    ...
    public HelpAction(string page) { ... }
    public void ShowHelpPage(object sender, System.EventArgs e) { ... }
}

HelpAction appInfo = new HelpAction("applicatie info");
button.Click += new EventHandler(appInfo.ShowHelpPage);

[ Voor 11% gewijzigd door Infinitive op 22-06-2004 11:02 ]

putStr $ map (x -> chr $ round $ 21/2 * x^3 - 92 * x^2 + 503/2 * x - 105) [1..4]


  • JeroenTheStig
  • Registratie: Mei 2000
  • Laatst online: 23:47
Infinitive schreef op 22 juni 2004 @ 11:02:
[...]


Met C# zou je het volgende kunnen doen:

C#:
1
2
3
4
5
6
7
8
9
class HelpAction
{
    ...
    public HelpAction(string page) { ... }
    public void ShowHelpPage(object sender, System.EventArgs e) { ... }
}

HelpAction appInfo = new HelpAction("applicatie info");
button.Click += new EventHandler(appInfo.ShowHelpPage);
Dit is inderdaad een nette manier :) thanx!

  • bramseltje
  • Registratie: September 2001
  • Laatst online: 23-05 10:13
[noob mode]
Je zou een klasse kunnen afleiden van de standaard CButton klasse, waarin je een eigen constructor opneemt die de koppeling met het gewenste helpitem regelt.

Dat zou betekenen dat je dus niet meer handmatig de help-page hoeft te wijzigen, en de button kunt aanmaken zoals in het Java voorbeeld dat je eerder gaf.

Op die manier hoef je die code voor de koppeling ook maar een keer te schrijven.

Maar goed, ik heb nog helemaal geen c# gebruikt, alleen ervaring met C++...
[/noob mode]

edit:

Je stopt dus de manier van Infinitive in de constructor, waarbij je de constructor van de button aanroept met de helpactie.

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
public class helpButton : public CButton
{
public:
  helpButton(String p_HelpActie)
  {
    ...
    HelpAction appInfo = new HelpAction("applicatie info");
    button.Click += new EventHandler(appInfo.ShowHelpPage);
    ...
  }

...
};


C#:
1
2
3
...
CButton l_HelpButton = new helpButton("Help Actie");
...

[ Voor 34% gewijzigd door bramseltje op 22-06-2004 11:54 ]


  • JeroenTheStig
  • Registratie: Mei 2000
  • Laatst online: 23:47
Bramseltje schreef op 22 juni 2004 @ 11:47:
[noob mode]
Je zou een klasse kunnen afleiden van de standaard CButton klasse, waarin je een eigen constructor opneemt die de koppeling met het gewenste helpitem regelt.

Dat zou betekenen dat je dus niet meer handmatig de help-page hoeft te wijzigen, en de button kunt aanmaken zoals in het Java voorbeeld dat je eerder gaf.

Op die manier hoef je die code voor de koppeling ook maar een keer te schrijven.

Maar goed, ik heb nog helemaal geen c# gebruikt, alleen ervaring met C++...
[/noob mode]

edit:

Je stopt dus de manier van Infinitive in de constructor, waarbij je de constructor van de button aanroept met de helpactie.

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
public class helpButton : public CButton
{
public:
  helpButton(String p_HelpActie)
  {
    ...
    HelpAction appInfo = new HelpAction("applicatie info");
    button.Click += new EventHandler(appInfo.ShowHelpPage);
    ...
  }

...
};


C#:
1
2
3
...
CButton l_HelpButton = new helpButton("Help Actie");
...
:D

Ook een hele leuke manier!! Er zijn dus mogelijkheden genoeg :)

  • JeroenTheStig
  • Registratie: Mei 2000
  • Laatst online: 23:47
Het idee van Bramseltje heb ik verder uitgewerkt. Ik zal even de code laten zien:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
public abstract class AbstractAction {
  private string _name;
  private AbstractAction(string name) {
    _name = name;
  }
  public string Name {
    get {
      return _name;
    }
  }
  public abstract void ActionPerformed();
}


overerving van System.Windows.Forms.Button. De J uit JButton staat voor de eerste letter van mijn voornaam ;) nee, ik ben niet java-geil :P
C#:
1
2
3
4
5
6
7
8
9
10
11
public class JButton : Button {
  private AbstractAction _action;
  public JButton(AbstractAction action) {
    _action = action;
    this.Text = _action.Name;
    this.Click += new EventHandler(ButtonEvent);
  }
  private void ButtonEvent(object sender, EventArgs e) {
    _action.ActionPerformed();
  }
}


overerving van de AbstractAction class: Hier staat dus de actionperformed code in, en ik kan de naam van knop invullen. Op deze manier kan ik dus door het veranderen van 1 regeltje alle knoppen die deze actie gebruiken een andere naam geven, bijvoorbeeld van 'exit' naar 'afsluiten' :)
C#:
1
2
3
4
5
6
7
8
9
10
public class ExitAction : AbstractAction {
  private string _toConsole;
  public ExitAction(string toConsole) : base("exit") { // exit is dus de naam van de component
    _toConsole = toConsole;
  }
  public override void ActionPerformed() {
    System.Console.WriteLine(_toConsole);
    Application.Exit();
  }
}


En zo initialiseer ik dus m'n knopjes:
C#:
1
2
3
4
5
..
..
JButton button = new JButton(new ExitAction("Applicatie wordt afgesloten"));
..
..


Geen gedonder meer met aparte methodes, ik kan parameters meesturen, ik zie met wat voor knop ik te maken heb en in de ExitAction is de naam van mijn knop gedefinieerd. Ik ben tevreden zo.

[ Voor 30% gewijzigd door JeroenTheStig op 23-06-2004 13:50 ]

Pagina: 1