Блокнот с вкладками - невозможно удалить кнопку закрытия

Я пытаюсь создать приложение-блокнот с вкладками, но возникают проблемы с удалением «кнопок закрытия» на вкладках. Вкладки удаляются должным образом, но я могу удалить только 1 кнопку закрытия. Может ли кто-нибудь помочь и направить меня в правильном направлении:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace My_Notepad
{
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }


    int TabCount = 0;
    int btx = 96;
    private int i;

    public void newBox()
    {

        TabPage tp = new TabPage("New Document          ");
        RichTextBox rtb = new RichTextBox();
        rtb.Dock = DockStyle.Fill;
        tp.Controls.Add(rtb);
        tabControl1.TabPages.Add(tp);
        this.tabControl1.SelectedTab = tp;
        this.tabControl1.Appearance = TabAppearance.FlatButtons;


        Button btnPlay = new Button();
        this.btnPlay = btnPlay;

        btnPlay.Width = 16;
        btnPlay.Height = 18;
        btnPlay.FlatStyle = FlatStyle.Flat;
        btnPlay.FlatAppearance.BorderSize = 0;
        btnPlay.Top = 25;
        btnPlay.Left = btx;
        btnPlay.Image = Image.FromFile(@"C:\\close-button.png");
        btnPlay.Click += new EventHandler(btnPlay_Click);
        this.Controls.Add(btnPlay);
        btnPlay.BringToFront();
        TabCount++;
        i++;

    }



    private void btnPlay_Click(object sender, EventArgs e)
    {

        tabControl1.SelectedTab.Dispose();
        this.Controls.Remove(btnPlay);

    }


    private void newToolStripMenuItem_Click(object sender, EventArgs e)
    {
        newBox();

        btx = btx + 126;
    }



    public Button btnPlay { get; set; }


   }
   }

person Jaco Hendriks    schedule 20.05.2015    source источник


Ответы (1)


Кажется, ваша проблема в том, что вы не храните отдельные ссылки на созданный вами Buttons. То, как вы написали код, предполагает, что у вас есть переменная уровня класса btnPlay, которой вы назначаете динамически создаваемую локальную переменную btnPlay, тем самым перезаписывая ссылку на старую Button:

Button btnPlay = new Button();
this.btnPlay = btnPlay;

Позже, когда вы попытаетесь удалить Buttons, вы сможете добраться только до последнего.

Чтобы избежать этого, вам нужно сохранить ссылки, которые соединяют каждую кнопку с TabPage, на которую она ссылается. Самый распространенный способ - использовать Tag ваших страниц для хранения ссылки:

Button btnPlay = new Button();
this.btnPlay = btnPlay;  
tp.Tag = btnPlay;

Теперь вы можете добраться до него, пока TabPage еще жив:

private void btnPlay_Click(object sender, EventArgs e)
{
    Button btnPlay = ((sender as TabPage).Tag as Button);
    ..
}

Однако, поскольку все, что вам нужно сделать, это избавиться от него, есть еще более простое решение: в событии btnPlay_Click у вас есть ссылка на правильный Button через параметр sender ..:

private void btnPlay_Click(object sender, EventArgs e)
{
    tabControl1.SelectedTab.Dispose();
    (sender as Button).Dispose();
}

Для этого вам даже не нужно использовать Tag .. Не уверен, что вы делаете что-нибудь с уровнем класса _17 _ .. ??

Однако ..

..насколько я понимаю, у вашего кода есть еще одна проблема: каждая кнопка закрытия закрывает только текущий выбранный TabPage вместо того, которому она принадлежит .. Итак, что мы на самом деле нужно, чтобы ссылка с каждого Button на его TabPage, а не наоборот ..:

Button btnPlay = new Button();
this.btnPlay = btnPlay;  // what is it good for?
btnPlay.Tag = tp;

Теперь это должно работать:

private void btnPlay_Click(object sender, EventArgs e)
{
    Button btnPlay = sender as Button;
    (btnPlay.Tag as TabPage).Dispose();
    btnPlay.Dispose();
}

Кстати, если в остальном вы довольны своим решением, обязательно придерживайтесь его! Просто хотел упомянуть, что обычно owner drawing TabControl используется для добавления украшений, таких как кнопки закрытия. Я бы сказал, что ваш способ звучит немного проще, по крайней мере, до тех пор, пока вы не захотите переместить или изменить размер вкладки ..

Обновление: раз уж вы спросили о рисовании владельцем, вот минимальный пример:

Rectangle currentCrossRect = Rectangle.Empty;

private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
{
    Bitmap cross = yourCloseImage;
    int xWidth = cross.Width;
    TabPage tp = tabControl1.TabPages[e.Index];
    e.DrawBackground();
    e.DrawFocusRectangle();
    Size size = tabControl1.ItemSize;
    using (SolidBrush brush = new SolidBrush(e.ForeColor))
        e.Graphics.DrawString(tp.Text, e.Font, brush, e.Bounds.Left + 2 , 5);
    if (tabControl1.SelectedTab == tp)
    {
        currentCrossRect = new Rectangle( 
                           e.Bounds.Left + size.Width - 20, 3, xWidth,xWidth);
        e.Graphics.DrawImage(cross, currentCrossRect.X, currentCrossRect.Y);
    }
}


private void tabControl1_MouseClick(object sender, MouseEventArgs e)
{
    TabPage tp = tabControl1.SelectedTab;

    if (currentCrossRect.Contains(e.Location)) tp.Dispose();
}
person TaW    schedule 20.05.2015
comment
Привет, TaW, Большое спасибо. Я применил ваше решение и отлично работает. Теперь я понимаю, что вы имеете в виду при изменении размера и перемещении вкладок - кнопки остаются на прежнем месте при закрытии вкладок. Я поиграюсь и посмотрю, смогу ли я пройти через это, если нет, я посмотрю на рисунок владельца. Еще раз спасибо - очень признателен - person Jaco Hendriks; 22.05.2015
comment
Рад, что это работает для вас. Если вы считаете, что на вопрос дан ответ, отметьте его как принятый. Для дальнейшего тестирования вы можете ознакомиться с этим сообщением - person TaW; 22.05.2015
comment
Привет, TaW, Похоже, мне нужно посмотреть на вариант рисования владельца, так как я не могу обойтись без того, что у меня сейчас есть. Знаете ли вы какие-нибудь хорошие уроки по рисованию владельцем конкретных кнопок закрытия вкладок? Спасибо и привет. - person Jaco Hendriks; 23.05.2015
comment
Здесь - решение, показывающее рисунок владельца. Обратите внимание, что на самом деле он рисует отдельные глифы на вкладках, а не только один «X», поэтому вы должны иметь возможность упростить его. Кстати: есть два способа показать кнопки закрытия: Firefox показывает их на каждой странице. VStudio только на активной вкладке. Последнее, очевидно, проще получить правильно. - person TaW; 23.05.2015
comment
Хотя это должно быть в отдельном вопросе, добавили минимальный код, используя только один x на выбранной вкладке .. - person TaW; 23.05.2015
comment
Спасибо, TaW - ты звезда. Я использовал приведенный выше код, и он отлично работает. Мне удалось немного изменить его, чтобы на каждой вкладке было изображение с событием щелчка. Очень признателен - person Jaco Hendriks; 24.05.2015