【问题标题】:Tabbed Notepad - not able to remove close button选项卡式记事本 - 无法删除关闭按钮
【发布时间】:2015-05-20 17:04:45
【问题描述】:

我正在尝试创建一个选项卡式记事本应用程序,但在删除选项卡上的“关闭按钮”时遇到问题。标签被删除,但我只能删除 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; }


   }
   }

【问题讨论】:

    标签: c# winforms tabs notepad


    【解决方案1】:

    您的问题似乎是,您没有单独引用您创建的Buttons。您编写代码的方式表明您有一个类级别变量btnPlay,您为其分配了一个动态创建的局部变量btnPlay,从而覆盖了对旧Button 的引用:

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

    稍后,当您尝试删除Buttons时,您只能到达最后一个。

    为避免这种情况,您需要保留将每个 Button 连接到它所引用的 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 事件中,您可以通过 sender 参数引用正确的 Button..:

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

    为此,您甚至不需要使用Tag.. 不确定您是否对班级级别btnPlay..??

    但是..

    ..按照我的阅读方式,您的代码还有一个问题:每个关闭按钮只关闭当前选择的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 drawingTabControl 来添加诸如关闭按钮之类的装饰。我会说,你的方式听起来有点简单,至少在你想移动或调整 Tab 大小之前..

    更新:既然您询问了所有者绘图,这里是一个最小的示例:

    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();
    }
    

    【讨论】:

    • 您好 TaW,非常感谢。我已经应用了您的解决方案并且效果很好。我现在明白了您在调整标签大小和移动标签时的意思 - 关闭标签时按钮保留在以前的位置。我会到处玩,看看我能不能克服它,如果不能,我会看看主人的画。再次感谢 - 非常感谢
    • 很高兴这对您有用。如果您认为问题已得到解答,请考虑将其标记为已接受。对于您的进一步测试,您可能想看看这个post
    • 嗨,TaW,看来我需要查看所有者绘图选项,因为我无法解决我目前拥有的问题。你知道关于所有者绘图的任何好的教程,专门用于标签的关闭按钮吗?谢谢和问候。
    • Here 是一个显示所有者绘图的解决方案。请注意,它实际上将单个字形绘制到选项卡上,而不仅仅是一个“X”,因此您应该能够简化它。顺便说一句:有两种方法可以显示关闭按钮:Firefox 在每个页面上显示它。 VStudio 仅在活动选项卡上。后者显然更容易正确..
    • 虽然它应该在一个单独的问题中,但添加了最少的代码,仅在所选选项卡上使用一个 x ..
    猜你喜欢
    • 2011-10-07
    • 1970-01-01
    • 2015-10-10
    • 1970-01-01
    • 1970-01-01
    • 2021-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多