Laden...

[gelöst] TabPage.Close() per Rechtsklick

Erstellt von bonzy vor 14 Jahren Letzter Beitrag vor 14 Jahren 3.521 Views
bonzy Themenstarter:in
157 Beiträge seit 2008
vor 14 Jahren
[gelöst] TabPage.Close() per Rechtsklick

Nabend,

Situation: Ich habe ein TabControl, dessen TabPages ich gerne über einen Rechtsklick auf die Registerkarte schließen würde. Da allerdings die TabPages nicht über ein geeignetes Click-Event verfügen und die Breite der Registerkarten nicht über die TabPage abrufbar ist, komme ich nicht voran. Es gibt zwar die ItemSize-Eigenschaft des TabControls, allerdings passt sich diese nicht an das angezeigte Element an oder Ähnliches.
Ich bin wirklich gerade etwas aufgeschmissen und würde gerne um eine "aufwändige" Lösung wie das selbstzeichnen oder Verändern des TabControls herumkommen.

Bin für jede Hilfe dankbar.

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo bonzy,

reicht es dir nicht, wenn man die TagPage durch einen Rechtsklick auf die Page selber statt auf den Reiter schießen könnte? Das wäre sicher viel leichter zu realisieren. Stichwort: TabPage.ContextMenu.

herbivore

916 Beiträge seit 2008
vor 14 Jahren

Hallo bonzy,

ich hab dir mal ne Lösung gepostet, die ist meines Erachtens nach gar nicht schwer ist daher leicht zu verstehen ist. Du hängst dich an das MouseClick Event und schaust welcher Button geclickt wurde. Danach überprüfst du ob der User ein TabPage (Reiter) gekickt hat. Ist dies der Fall dann öffnest du ein ContextMenu wobei du die Tabpage gleich mit an die TagProperty hängst. Danach musst du im OnClick des MenuItems nur noch die Tabpage removen. Und fertig!


public class ClickableTabControl : TabControl
{
    /// <summary>
    /// Raises the <see cref="E:System.Windows.Forms.Control.MouseClick"/> event.
    /// </summary>
    /// <param name="e">An <see cref="T:System.Windows.Forms.MouseEventArgs"/> that contains the event data.</param>
    protected override void OnMouseClick(MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Right)
        {
            for (int i = 0; i < this.TabCount; i++)
            {
                if (TabPageClicked(e.Location, i))
                {
                    ContextMenu menu = new ContextMenu();
                    MenuItem item = new MenuItem("Close", new EventHandler(CloseClick));
                    item.Tag = this.TabPages[i];
                    menu.MenuItems.Add(item);
                    menu.Show(this, e.Location);
                }
            }
        }
        base.OnMouseClick(e);
    }

    /// <summary>
    /// Closes the tabpage the user specified.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
    private void CloseClick(object sender, EventArgs e)
    {
        MenuItem item = sender as MenuItem;
        if (item != null)
        {
            TabPage page = item.Tag as TabPage;
            if (page != null)
            {
                this.TabPages.Remove(page);
            }
        }
    }

    /// <summary>
    /// Return true if the tabpage which with the given index was clicked.
    /// </summary>
    /// <param name="point">The point.</param>
    /// <param name="i">The i.</param>
    /// <returns></returns>
    private bool TabPageClicked(Point point, int i)
    {
        Rectangle rect = this.GetTabRect(i);
        
        return rect.Contains(point);
    }
}

Again what learned...

5.299 Beiträge seit 2008
vor 14 Jahren

In [ExtensionMethods] TabControlX ist mein Ansatz, Tabcontrol.Click auszuwerten, und per Tabcontrol.GetTabRect() zu checken, ob und welcher Reiter geklickt wurde.
Es sind ja fast immer die Reiter, auf die geklickst wird, auf andere Bereiche des Tabcontrolss kann man ja garnicht klicksen, weil da annere Controls drauf sind.

Der frühe Apfel fängt den Wurm.

916 Beiträge seit 2008
vor 14 Jahren

@ErfinderDesRades

Das ist äquivalent zu meiner Lösung 😃

Again what learned...

5.299 Beiträge seit 2008
vor 14 Jahren

jau. (mal wieder gepennt)

Der frühe Apfel fängt den Wurm.

bonzy Themenstarter:in
157 Beiträge seit 2008
vor 14 Jahren

Danke für die Lösungen. Werde aber meine eigene weiterbenutzen und nur auf "Rectangle rect = this.GetTabRect(i);" zurückgreifen. 😉

916 Beiträge seit 2008
vor 14 Jahren

Werde aber meine eigene weiterbenutzen und nur auf "Rectangle rect = this.GetTabRect(i);" zurückgreifen.

Aber du hattest doch gar keine eigene Lösung, wieso dann also weiterbenutzen? Unsere (die von ErfinderDesRades und mir) funktioniert doch einwandfrei, was gibt es daran auszusetzen?

Again what learned...

bonzy Themenstarter:in
157 Beiträge seit 2008
vor 14 Jahren

Ich habe eine eigene unvollständige Lösung, die bloß nicht korrekt feststellten konnte, auf welche Registerkarte geklickt wurde. Aufgrund der GetTabRect()-Methode kann ich das nun und somit ist sie lauffähig. An euren Lösungen gibt es nichts auszusetzen, aber das muss ja nicht heißen, dass ich unbedingt darauf zurückgreife.

916 Beiträge seit 2008
vor 14 Jahren

Das stimmt, aber da du schreibst ich werde "aber" meine Lösung weiter benutzten, schließe ich daraus das deine Lösung Vorteile hat. Lass uns an diesen Vorteilen teilhaben.

Again what learned...

bonzy Themenstarter:in
157 Beiträge seit 2008
vor 14 Jahren

Das stimmt, aber da du schreibst ich werde "aber" meine Lösung weiter benutzten, schließe ich daraus das deine Lösung Vorteile hat. Lass uns an diesen Vorteilen teilhaben.

Der "Vorteil" besteht darin, dass sie schon eingebaut ist? Grundsätzlich war ja auch nicht die Frage nach einer Komplettlösung, sondern nach einem Weg, die Breite einer Registerkarte abzufragen. Dabei habt ihr mir geholfen und diese Hilfe habe ich in mein Programm einfließen lassen. Mehr steckt da nicht hinter und denke damit ists auch gut.

916 Beiträge seit 2008
vor 14 Jahren

Ok, ändere den Titel bitte noch in [gelöst] ab.

Again what learned...