簡體   English   中英

Winforms 標簽頁上的關閉按鈕

[英]Close button on Tab pages in Winforms

我試圖在 TabControl 的標簽頁上添加一個關閉按鈕,並在鼠標懸停在其上時將關閉按鈕的顏色從淺灰色更改為黑色。 但是,顏色永遠不會改變。

創建 DrawEventArgsCustom 類以指示鼠標懸停在關閉按鈕上。 如果為真,則執行更改顏色的語句,但顏色永遠不會改變。

private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
{
    try
    {

        Rectangle r = e.Bounds;
        r = this.tabControl1.GetTabRect(e.Index);
        r.Offset(2, 2);
        Brush TitleBrush = new SolidBrush(Color.Black);
        Brush CloseBrush = new SolidBrush(Color.Gray);
        Brush CloseBrushSelected = new SolidBrush(Color.Black);
        Font f = this.Font;
        string title = this.tabControl1.TabPages[e.Index].Text;

        e.Graphics.DrawString(title, f, TitleBrush, new PointF(r.X, r.Y));
        if (e is DrawEventArgsCustom)
        {
            if (((DrawEventArgsCustom)e) != null && ((DrawEventArgsCustom)e).HoverTrue == true)
                e.Graphics.DrawString("x", f, CloseBrushSelected, new PointF
             (r.X + (this.tabControl1.GetTabRect(e.Index).Width - _imageLocation.X), _imageLocation.Y));
        }
        e.Graphics.DrawString("x", f, CloseBrush, new PointF
              (r.X + (this.tabControl1.GetTabRect(e.Index).Width - _imageLocation.X), _imageLocation.Y));


    }
    catch (Exception ex)
    {

    }
}

private void tabControl1_MouseMove(object sender, MouseEventArgs e)
{
    Rectangle mouseRect = new Rectangle(e.X, e.Y, 1, 1);
    Graphics graphics = CreateGraphics();
    for (int i = 0; i < tabControl1.TabCount; i++)
    {
        if (tabControl1.GetTabRect(i).IntersectsWith(mouseRect))
        {

            tabControl1_DrawItem(this, new DrawEventArgsCustom(hoverTrue: true, graphics, this.Font, mouseRect, i, DrawItemState.Focus));

        }
    }
}

class DrawEventArgsCustom : DrawItemEventArgs
{


    public DrawEventArgsCustom(bool hoverTrue, Graphics graphics, Font font, Rectangle rect, int index, DrawItemState drawItemState)
        : base(graphics, font, rect, index, drawItemState)
    {
        this.HoverTrue = hoverTrue;
        this.Graph = graphics;
        this.Fnt = font;
        this.Rect = rect;
        this.ind = index;
        this.drawItemSt = drawItemState;
    }


    public bool HoverTrue { get; private set; }
    public Graphics Graph { get; private set; }
    public Font Fnt { get; private set; }
    public Rectangle Rect { get; private set; }
    public int ind { get; private set; }
    public DrawItemState drawItemSt { get; private set; }
}

不需要像那樣創建新的Graphics對象,您應該在DrawItem事件中完成所有繪圖。 例如在這種情況下:

//a class level variable.
private int HoverIndex = -1;

private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
{
    var g = e.Graphics;
    var tp = tabControl1.TabPages[e.Index];
    var rt = e.Bounds;
    var rx = new Rectangle(rt.Right - 20, (rt.Y + (rt.Height - 12)) / 2 + 1, 12, 12);

    if ((e.State & DrawItemState.Selected) != DrawItemState.Selected)
    {
        rx.Offset(0, 2);
    }

    rt.Inflate(-rx.Width, 0);
    rt.Offset(-(rx.Width / 2), 0);

    using (Font f = new Font("Marlett", 8f))
    using (StringFormat sf = new StringFormat()
    {
        Alignment = StringAlignment.Center,
        LineAlignment = StringAlignment.Center,
        Trimming = StringTrimming.EllipsisCharacter,
        FormatFlags = StringFormatFlags.NoWrap,
    })
    {
        g.DrawString(tp.Text, tp.Font ?? Font, Brushes.Black, rt, sf);
        g.DrawString("r", f, HoverIndex == e.Index ? Brushes.Black : Brushes.LightGray, rx, sf);
    }
    tp.Tag = rx;
}

請注意,現在每個TabPage控件的Tag屬性都TabPage x按鈕的矩形。

MouseMove事件中迭代TabPages ,從Tag屬性投射x矩形,檢查x矩形是否包含當前的e.Location ,然后調用Invalidate(); TabControl更新繪圖的方法:

private void tabControl1_MouseMove(object sender, MouseEventArgs e)
{
    for (int i = 0; i < tabControl1.TabCount; i++)
    {
        var rx =(Rectangle)tabControl1.TabPages[i].Tag;

        if (rx.Contains(e.Location))
        {
            //To avoid the redundant calls. 
            if (HoverIndex != i)
            {
                HoverIndex = i;
                tabControl1.Invalidate();
            }
            return;
        }
    }

    //To avoid the redundant calls.
    if (HoverIndex != -1)
    {
        HoverIndex = -1;
        tabControl1.Invalidate();
    }
}

如有必要,在MouseLeave事件中無效:

private void tabControl1_MouseLeave(object sender, EventArgs e)
{
    if (HoverIndex != -1)
    {
        HoverIndex = -1;
        tabControl1.Invalidate();
    }
}

要關閉/處理頁面,請處理MouseUp事件:

private void tabControl1_MouseUp(object sender, MouseEventArgs e)
{
    for(int i = 0; i < tabControl1.TabCount; i++)
    {
        var rx = (Rectangle)tabControl1.TabPages[i].Tag;

        if (rx.Contains(rx.Location)) //changed e.Location to rx.Location
        {
            tabControl1.TabPages[i].Dispose();
            return;
        }                                    
    }
}

相關文章

帶有關閉和添加按鈕的 TabControl

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM