[.NET] Toolbar runtime uitbreiden incl. eventhandling

Pagina: 1
Acties:

  • JeroenTheStig
  • Registratie: Mei 2000
  • Laatst online: 23:47
Ik ben bezig met een programma dat gebruik maakt van losse modules. De standaard applicatie bevat een toolbar met enkele toolbarButtons.

Nu wil ik graag dat de losse modules de toolbar kan uitbreiden met eigen toolbarbuttons.

Het probleem is echter dat ik niet meerdere toolbars naast elkaar kan plaatsen. Als ik de dockstyle van de toolbars op 'top' zet, dan worden ze onder elkaar geplaatst. Als ik dus 10 verschillende toolbar 'groepen' op de panel plaats, dan is m'n panel vol.

Ik kan aan de toolbar natuurlijk extra knoppen toevoegen, maar het probleem is dat niet de toolbarbutton, maar de toolbar zélf de events bevat. Ik begrijp nog steeds niet waarom ze dat hebben gedaan, maar ja, er valt niks aan te doen.

Op deze manier komt het op dit moment er dus uit te zien:

C#:
1
2
3
4
5
6
7
8
9
...
...
ToolBar bar = new ToolBar();
bar.Buttons.Add(new ToolBarButton("knop1");
bar.Buttons.Add(new ToolBarButton("knop2");
bar.Buttons.Add(new ToolBarButton("knop3");
bar.ButtonClick += new ToolBarButtonClickEventHandler(BlaButtonClick);
...
...


De eventafhandeling gaat dus op deze manier:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
protected void BlaButtonClick (object sender, ToolBarButtonClickEventArgs e)
{
  switch(this.Buttons.IndexOf(e.Button))
  {
    case 0:
    // code
    break;
    case 1:
    // code 
    break;
    case 2:
    // code
    break;
}


Kortom: je kunt op deze manier dus geen extra toolbar buttons toevoegen vanuit de modules, want je kunt aan deze knop geen click handler meegeven.

Is er iemand die weet of het mogelijk is om extra knoppen mét handler toe te voegen? Wat nog mooier is is een manier waarop toolbars netjes naast elkaar worden geplaatst en niet onder elkaar.

[ Voor 3% gewijzigd door JeroenTheStig op 06-07-2004 18:37 ]


  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 22-05 23:32

alienfruit

the alien you never expected

Nou je kan toch meerdere ButtonClicks events toevoegen neem ik aan?

  • Juicy
  • Registratie: December 2000
  • Laatst online: 24-05 12:51
Dit is inderdaad ook weer een van die zaken die erg raar geregeld zijn ! Een oplossing zou zijn om zelf een toolbar in elkaar te knutselen. Is in principe niet zo heel veel werk en, mits goed opgezet, ook bruikbaar in eventuele andere projecten.

Je hebt geluk ! Iemand heeft het al voor je gedaan ! ;)
http://www.codeproject.com/cs/menu/extendedtoolbar.asp

[ Voor 59% gewijzigd door Juicy op 06-07-2004 18:22 ]

-


  • JeroenTheStig
  • Registratie: Mei 2000
  • Laatst online: 23:47
Juicy schreef op 06 juli 2004 @ 18:11:
Dit is inderdaad ook weer een van die zaken die erg raar geregeld zijn ! Een oplossing zou zijn om zelf een toolbar in elkaar te knutselen. Is in principe niet zo heel veel werk en, mits goed opgezet, ook bruikbaar in eventuele andere projecten.

Je hebt geluk ! Iemand heeft het al voor je gedaan ! ;)
http://www.codeproject.com/cs/menu/extendedtoolbar.asp
yeah!! Ik ga het direct uitproberen :) thanx!

  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 22-05 23:32

alienfruit

the alien you never expected

Maar als je meerdere events hangt aan die ButtonClick wordt dan echt de eerste alleen maar uitgevoerd?

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:52
alienfruit schreef op 06 juli 2004 @ 19:47:
Maar als je meerdere events hangt aan die ButtonClick wordt dan echt de eerste alleen maar uitgevoerd?
Ik denk het niet, het zal wel een multicast delegate zijn.
Maar dan nog, moet je in de event zelf gaan nagaan op welke button er geklikt werd, of welke button de click veroorzaakt heeft.

Zoals al gezegd werd: dit is echt een hele rare, en imo ranzige oplossing. Het had beter geweest als iedere Button apart een OnClick event had, ipv 1 OnClick event voor de hele toolbar.

https://fgheysels.github.io/


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:52
offtopic:

Ik heb net eens in C# 2.0 gekeken.
Je hebt in .NET 2.0 een 'ToolStrip' control, en daar kan je aan een individueel item onder andere een click event hangen.

https://fgheysels.github.io/


  • JeroenTheStig
  • Registratie: Mei 2000
  • Laatst online: 23:47
whoami schreef op 06 juli 2004 @ 20:20:
offtopic:

Ik heb net eens in C# 2.0 gekeken.
Je hebt in .NET 2.0 een 'ToolStrip' control, en daar kan je aan een individueel item onder andere een click event hangen.
ah cool!! Trouwens, klopt het dat microsoft.net 2.0 over meer geavanceerde GUI componenten beschikt? Het is namelijk vrij frustrerend dat je dockable windows, mooie menubars en toolbars zelf in elkaar moet knutselen..

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:52
Er zitten wel een aantal nieuwe componenten in, maar of het zoveel verschil uitmaakt? :?
Ik heb ze nog niet allemaal bekeken en getest, maar dockable windows heb ik nog niet echt gezien.
De toolbar en menu componenten zijn wel wat 'verfraaid'.

https://fgheysels.github.io/


  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 22-05 23:32

alienfruit

the alien you never expected

Ik gebruik gewoon zelf de DevExpress Winforms Suite :D

  • JeroenTheStig
  • Registratie: Mei 2000
  • Laatst online: 23:47
alienfruit schreef op 06 juli 2004 @ 20:44:
Ik gebruik gewoon zelf de DevExpress Winforms Suite :D
wasda?

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:52
Wij gebruiken ook een aantal controls van DevExpress. Het is een control suite waar je wat geld moet voor neerlappen.
(Wij gebruiken die grid en cardviews oa.)

https://fgheysels.github.io/


Verwijderd

Aan de andere kant, al is er standaard geen support voor dockable windows, echt moeilijk is het ook weer niet om het zelf te maken.

Voor het probleem van de TS:
Maakt je module zelf de knoppen aan op de toolbar? Dan weet hij in theorie ook welke knoppen onder welk nummer zit. De buttons.add function geeft de ID terug van de knop die je toevoegt, dus bijhouden van wie welke knoppen zijn is niet zo lastig. Als je dan in je module een functie opneemt die je aanroept vanuit je button click event ben je toch eigenlijk al klaar?

  • alienfruit
  • Registratie: Maart 2003
  • Laatst online: 22-05 23:32

alienfruit

the alien you never expected

Kijk eens op www.devexpress.com zou ik zeggen, kwalitatief goed spul (beter dan componentOne crap).

  • JeroenTheStig
  • Registratie: Mei 2000
  • Laatst online: 23:47
Ik kom er even niet meer uit. Ik gebruik nu de ToolbarFunction (http://www.codeproject.com/cs/menu/extendedtoolbar.asp) waarbij ik een toolbarbutton kan koppelen aan een menuitem die de event afhandelt.

De volgende code werkt prima:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
...
MenuItem menuItemExit = new MenuItem();
ToolbarFunction toolbarFunction = new ToolbarFunction();
ToolBar toolBar = new ToolBar();
ToolBarButton exitButton = new ToolBarButton();

menuItemExit.Click += new EventHandler(menuItemExit_Click);

toolBar.AddRange(new ToolBarButton[] {exitButton});

toolbarFunction.SetToolbarFunction(exitButton,menuItemExit);

// code om de componenten op de pane te gooien er tussenuit gesloopt, 
// is verder niet interessant
...

private void menuItemExit_Click(object sender, System.EventArgs e)
{
  System.Console.WriteLine("Exit Click!");
}


Dit heeft m'n c#builder er van gemaakt, en als ik op de toolbarbutton klik, wordt netjes "Exit Click!" in m'n console geplaatst.

Aangezien ik bezig ben met een programma waar runtime extra toolbarbuttons kunnen worden toegevoegd door de modules, moet ik een stuk code schrijven waar netjes een collectie knoppen worden toegevoegd met de daarbij behorende acties.

Ik heb daarvoor de volgende code gebouwd:

Als eerste een klasse die ToolBar overerft:

C#:
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public class NewToolBar : ToolBar
{
    private int _numberOfToolButtons = 0;
    private ImageList _imageList;
    private Tools.ToolbarFunction _toolbarFunction;

    public NewToolBar()
    {
        _imageList = new ImageList();
        this.ImageList = _imageList;
        _toolbarFunction = new ToolbarFunction();
        this.InitToolbar();
        this.Add(GetMainButtons());
    }

    private void InitToolbar()
    {
            // toolbar grafische settings: weggehaald, niet interessant
    }

    public void Add(ExpToolBarButton[] buttons)
    {
        for (int i = 0; i < buttons.Length; i++)
        {
            _imageList.Images.Add(buttons[i].Icon);
            buttons[i].ImageIndex = i + _numberOfToolButtons;
            SetAction(buttons[i]);
        }

        this.Buttons.AddRange(buttons);
        _numberOfToolButtons += buttons.Length;
    }

    private void SetAction(ExpToolBarButton toolbarButton)
    {
        ExpMenuItem menuItem = new ExpMenuItem(toolbarButton.Action);
        _toolbarFunction.SetToolbarFunction(toolbarButton, menuItem);
    }


    private ExpToolBarButton[] GetMainButtons()
    {

        // new project
        Bitmap bitmapNew = new Bitmap
                            (@"C:\rootMapViewer\files\icons\new_page.gif");
        AbstractAction actionNew = new FileNewProjectAction();
        ExpToolBarButton toolbarNew = new ExpToolBarButton(bitmapNew,actionNew);    

        return new ExpToolBarButton[]{
                toolbarNew
        };
    }
}


ExpToolBarButton overerft ToolBarButton en bevat de daarbijbehorende icoon en actie die uitgevoerd moet worden:

C#:
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
32
33
34
35
36
37
38
39
40
41
42
43
44
public class ExpToolBarButton : ToolBarButton
    {
        private Bitmap _icon;
        private AbstractAction _action;

        public ExpToolBarButton () {}

        public ExpToolBarButton (Bitmap icon, AbstractAction action)
        {             
            _icon = icon;
            _action = action;
        }

        public ExpToolBarButton (Bitmap icon, AbstractAction action, string text)
        {
            _icon = icon;
            _action = action;
            this.Text = text;
        }

        public Bitmap Icon
        {
            set
            {
                _icon = value;
            }
            get
            {
                return _icon;
            }
        }

        public AbstractAction Action
        {
            set
            {
                _action = value;
            }
            get
            {
                return _action;
            }
        }
    }


En tot slot de ExpMenuItem die MenuItem overerft.

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class ExpMenuItem: System.Windows.Forms.MenuItem
    {
        private AbstractAction _action;

        public ExpMenuItem(AbstractAction action)
        {
            _action = action;
            this.Text = _action.Name;
            this.Click += new EventHandler(MenuItemEvent);
        }

        private void MenuItemEvent(object sender, System.EventArgs e)
        {
            _action.ActionPerformed();
        }
    }


In de FileNewProjectAction wordt in de ActionPerformed methode een stringetje naar de console gepasst. het idee van deze code is dat ik vanuit m'n module dus de toolbarbutton toevoeg inclusief de bitmap en de abstractaction.

Het probleem is dat deze actie dus niet wordt uitgevoerd. Ik heb met de debugger gekeken of hij uberhaupt de click event wel toevoegd in de ToolbarFunction, en dat lijkt allemaal goed te gaan. De menuItem waar de event aan hangt hoeft verder ook niet toegevoegd te worden aan de frame, dus dat is het ook niet.
Ik hoop dat iemand kan zien wat er fout gaat, want ik kom er niet meer uit

[ Voor 3% gewijzigd door JeroenTheStig op 08-07-2004 11:32 ]


  • JeroenTheStig
  • Registratie: Mei 2000
  • Laatst online: 23:47
Ik heb die gare ToolbarFunction maar overboord gegooid en het volgende er van gemaakt:

C#:
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
public class NewToolBar : ToolBar
{
    private int _numberOfToolButtons = 0;
    private ImageList _imageList;
    private ArrayList _toolBarComponents;

    public NewToolBar()
    {
        _imageList = new ImageList();
        _toolBarComponents = new ArrayList();
        this.ImageList = _imageList;
        this.Add(GetMainButtons());
        this.ButtonClick += new ToolBarButtonClickEventHandler(ToolbarButton_Click);
    }

    public void Add(ToolBarComponent[] buttons)
    {
        _toolBarComponents.AddRange(buttons);
        ToolBarButton[] buttonArray = new ToolBarButton[buttons.Length];
        for (int i = 0; i < buttons.Length; i++)
        {
            buttonArray[i] = buttons[i].ToolBarButton;
            _imageList.Images.Add(buttons[i].Icon);
            buttonArray[i].ImageIndex = i + _numberOfToolButtons;
        }

        this.Buttons.AddRange(buttonArray);
        _numberOfToolButtons += buttons.Length;
    }


    private ToolBarComponent[] GetMainButtons()
    {
        // new project
        Bitmap bitmapNew = new Bitmap
                            (@"C:\rootMapViewer\files\icons\new_page.gif");
        ToolBarButton toolbarButton = new ToolBarButton();
        toolbarButton.ToolTipText = "test";
        AbstractAction actionNew = new FileNewProjectAction();
        ToolBarComponent toolbarNew = new ToolBarComponent(bitmapNew,
                                                        actionNew,
                                                        toolbarButton);
                return new ToolBarComponent[]{
                toolbarNew
        };
    }

    private void ToolbarButton_Click(object sender, ToolBarButtonClickEventArgs e)
    {
        bool notFound = true;
        IEnumerator myEnumerator = _toolBarComponents.GetEnumerator();
        while ( myEnumerator.MoveNext() && notFound)
        {
            ToolBarButton clickedOne = ((ToolBarComponent)myEnumerator.Current).ToolBarButton;
            if (clickedOne == e.Button)
            {
                ((ToolBarComponent)myEnumerator.Current).Action.ActionPerformed();
                notFound = false;
            }
        }
    }

}


En dan gaat het dus om die void ToolbarButton_Click. Tja, het blijft jammer dat de knoppen niet zelf een eventje hebben, maar op deze manier werkt het ook wel.
Pagina: 1