0

我需要一个具有不同 TabPage Header 的自定义 TabControl。我已将 DrawMode 属性设置为“OwnerDrawFixed”,以便调用 OnDrawItem 方法。

在 OnDrawItem 方法中,我这样做:

        protected override void OnDrawItem(DrawItemEventArgs e)
    {
        base.OnDrawItem(e);

        var tabPage = TabPages[e.Index];
        if (tabPage != null) 
        {
            if (tabPage is BackOfficeTabPage) 
            {
                ((BackOfficeTabPage)tabPage).DrawTab(e.Graphics, GetTabRect(e.Index));
            }
        }
    }

将为每个现有页面调用该代码,并带有匹配的索引。但无论我做什么,它总是使用相同的 Header。

他正在绘制的矩形似乎是正确的。我也试过这样:

        protected override void OnDrawItem(DrawItemEventArgs e)
    {
        base.OnDrawItem(e);

        var tabPage = TabPages[e.Index];
        if (tabPage != null) 
        {
            if (tabPage is BackOfficeTabPage) 
            {
                ((BackOfficeTabPage)tabPage).DrawTab(e.Graphics, e.Bounds);
            }
        }
    }

结果相同。那是我的 DrawTab 函数:

        internal void DrawTab(Graphics g, Rectangle rect) 
    {
        if (State != null) 
        {
            if (State.HasInvalidBuffers()) 
            {
                CreateFrames(rect);
            }
            if (State.IsInvalidate) 
            {
                g.SmoothingMode = SmoothingMode.HighQuality;
                g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                if (State.IsHover)
                {
                    g.DrawImage(State.HoverBufferFrame, rect);
                }
                else if (State.IsSelected)
                {
                    g.DrawImage(State.SelectionBufferFrame, rect);
                }
                else 
                {
                    g.DrawImage(State.DefaultBufferFrame, rect);
                }
                if (State.IsCloseFocused)
                {
                    g.DrawImage(State.FocusedCloseButtonBufferFrame, State.CloseButtonRectangle);
                }
                else 
                {
                    g.DrawImage(State.DefaultCloseButtonBufferFrame, State.CloseButtonRectangle);
                }
                State.IsInvalidate = false;
            }
        }
    }

每个选项卡都应该是橙色的。但只有第一个会正确显示。(图片链接)

我不明白我的错误。

我希望有人能启发我:)

此致,

西蒙

*****更新***** 这是 TabPage 控件的完整代码,它正在执行选项卡绘制。我不确定为什么,但第二个选项卡中的缓冲区图像始终是透明的。

    public sealed class BackOfficeTabPage : TabPage
{
    #region Fields
    private string _text = string.Empty;
    private string _imageKey = string.Empty;
    private TabState _tabstate = new TabState();
    private Brush _regluarBrush = new SolidBrush(Color.Transparent);
    private Brush _selectedBrush = null;
    private Brush _hoverBrush = null;
    private int _imageIndex = 0;
    #endregion
    #region Properties
    public Brush RegularBrush 
    {
        get 
        { 
            return _regluarBrush; 
        }
        set 
        {
            _regluarBrush = value;
            _tabstate.InvalidateImageBuffers();
            _tabstate.IsInvalidate = true;
            if (ParentTabControl != null)
                ParentTabControl.Invalidate();
        }
    }
    public Brush SelectedBrush 
    {
        get 
        {
            return _selectedBrush;
        }
        set 
        {
            _selectedBrush = value;
            _tabstate.InvalidateImageBuffers();
            _tabstate.IsInvalidate = true;
            if (ParentTabControl != null)
                ParentTabControl.Invalidate();
        }
    }
    public Brush HoverBrush 
    {
        get 
        {
            return _hoverBrush;
        }
        set 
        {
            _hoverBrush = value;
            _tabstate.InvalidateImageBuffers();
            _tabstate.IsInvalidate = true;
            if (ParentTabControl != null)
                ParentTabControl.Invalidate();
        }
    }
    public BackOfficeTabControl ParentTabControl
    {
        get 
        {
            if (Parent != null && Parent is BackOfficeTabControl)
                return (BackOfficeTabControl)Parent;
            return null;
        }
    }
    public new int ImageIndex
    {
        get
        {
            return _imageIndex;
        }
        set
        {
            _tabstate.InvalidateImageBuffers();
            _tabstate.IsInvalidate = true;
            if (OnPropertyChanged != null)
                OnPropertyChanged(this, new PropertyChangedEventArgs("ImageIndex", _imageIndex, value));
            _imageIndex = value;
            base.ImageIndex = value;
        }
    }
    public new string ImageKey
    {
        get
        {
            return _imageKey;
        }
        set
        {
            _tabstate.InvalidateImageBuffers();
            _tabstate.IsInvalidate = true;
            if (OnPropertyChanged != null)
                OnPropertyChanged(this, new PropertyChangedEventArgs("ImageKey", _imageKey, value));
            _imageKey = value;
            base.ImageKey = value;
        }
    }
    public TabState State 
    {
        get 
        {
            return _tabstate;
        }
        set 
        {
            if (OnPropertyChanged != null)
                OnPropertyChanged(this, new PropertyChangedEventArgs("State", _tabstate, value));
            _tabstate = value;
        }
    }
    public new string Text
    {
        get { return _text; }
        set
        {
            _tabstate.InvalidateImageBuffers();
            _tabstate.IsInvalidate = true;
            if (OnPropertyChanged != null)
                OnPropertyChanged(this, new PropertyChangedEventArgs("Text", _text, value));
            _text = value;
            base.Text = value;
        }
    }
    public Image AssocImage 
    {
        get 
        {
            Image image = null;
            if ((!string.IsNullOrEmpty(ImageKey) || ImageIndex >= 0) && ParentTabControl.ImageList != null)
            {
                if (!string.IsNullOrEmpty(ImageKey))
                    image = ParentTabControl.ImageList.Images[ImageKey];
                else
                    image = ParentTabControl.ImageList.Images[ImageIndex];
            }
            return null;
        }

    }
    #endregion
    #region Events
    public event EventHandler<PropertyChangedEventArgs> OnPropertyChanged = null;
    #endregion

    #region Functions
    internal void test(Rectangle rect) 
    {
        if (State.HasInvalidBuffers())
        {
            CreateFrames(rect);
        }
    }
    internal void DrawTab(Graphics g, Rectangle rect) 
    {
        if (State != null) 
        {
            if (State.HasInvalidBuffers()) 
            {
                CreateFrames(rect);
            }
            if (State.IsInvalidate) 
            {
                g.SmoothingMode = SmoothingMode.HighQuality;
                g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                if (State.IsHover)
                {
                    g.DrawImage(State.HoverBufferFrame,rect, rect.X, rect.Y, rect.Width, rect.Height, GraphicsUnit.Pixel);
                }
                else if (State.IsSelected)
                {
                    g.DrawImage(State.SelectionBufferFrame, rect, rect.X, rect.Y, rect.Width, rect.Height, GraphicsUnit.Pixel);
                }   
                else 
                {
                    g.DrawImage(State.DefaultBufferFrame, rect, rect.X, rect.Y, rect.Width, rect.Height, GraphicsUnit.Pixel);
                }
                if (State.IsCloseFocused)
                {
                    g.DrawImage(State.FocusedCloseButtonBufferFrame, rect, rect.X, rect.Y, rect.Width, rect.Height, GraphicsUnit.Pixel);
                }
                else 
                {
                    g.DrawImage(State.DefaultCloseButtonBufferFrame, rect, rect.X, rect.Y, rect.Width, rect.Height, GraphicsUnit.Pixel);
                }
                State.IsInvalidate = false;
            }
        }
    }
    internal void CreateFrames(Rectangle rect) 
    {
        Image image = AssocImage;
        Rectangle imageRectangle = Rectangle.Empty, textRectangle = Rectangle.Empty, closeButtonRectangle = Rectangle.Empty;
        if (image != null) 
        {
            imageRectangle = new Rectangle(rect.X + 2, rect.Y + 2, ParentTabControl.ImageScaling.Width, ParentTabControl.ImageScaling.Height);
        }
        if (ParentTabControl != null && ParentTabControl.ShowCloseButton && ParentTabControl.CloseButtonImage != null) 
        {
            closeButtonRectangle = new Rectangle(rect.X + rect.Width - (16), rect.Y + 2, 14, 14);
        }
        if (!string.IsNullOrEmpty(Text)) 
        {
            if (imageRectangle != Rectangle.Empty)
            {

                if (closeButtonRectangle != Rectangle.Empty)
                {
                    textRectangle = new Rectangle(imageRectangle.X + imageRectangle.Width + 1, rect.Y, closeButtonRectangle.X - (imageRectangle.X + imageRectangle.Width + 2), rect.Height);
                }
                else 
                {
                    textRectangle = new Rectangle(imageRectangle.X + imageRectangle.Width + 1, rect.Y, rect.X + rect.Width - (imageRectangle.X + imageRectangle.Width + 2), rect.Height);                    
                }

            }
            else 
            {
                if (closeButtonRectangle != Rectangle.Empty)
                {
                    textRectangle = new Rectangle(rect.X + 1, rect.Y, closeButtonRectangle.X - (rect.X + 2), rect.Height);
                }
                else 
                {
                    textRectangle = new Rectangle(rect.X + 1, rect.Y, rect.Width - 2, rect.Height);
                }
            }
        }
        State.ImageRectangle = rect;
        State.CloseButtonRectangle = closeButtonRectangle;
        CreateSelectionFrame(rect, imageRectangle, textRectangle);
        CreateHoverFrame(rect, imageRectangle, textRectangle);
        CreateDefaultFrame(rect, imageRectangle, textRectangle);
        CreateCloseButtonFrames(closeButtonRectangle);

    }

    internal void CreateSelectionFrame(Rectangle rect, Rectangle imageRect, Rectangle textRect)
    {
        if (rect != Rectangle.Empty) 
        {
            Image buffer = new Bitmap(rect.Width, rect.Height, PixelFormat.Format32bppArgb);
            using (Graphics g = Graphics.FromImage(buffer)) 
            {
                g.Clear(Color.Transparent);
                g.SmoothingMode = SmoothingMode.HighQuality;
                g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
                g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                Color light = SystemColors.Window, dark = Color.FromArgb(229, 195, 101);
                g.FillRectangle(new LinearGradientBrush(rect, light, dark, LinearGradientMode.Vertical), rect);
                if (imageRect != Rectangle.Empty)
                {
                    Image img = AssocImage;
                    if (img != null)
                    {
                        g.DrawImage(img, imageRect);
                    }
                }
                if (!string.IsNullOrEmpty(Text) && textRect != Rectangle.Empty)
                {
                    StringFormat format = new StringFormat();
                    format.Alignment = StringAlignment.Center;
                    format.Trimming = StringTrimming.EllipsisCharacter;
                    g.DrawString(Text, this.Font, new SolidBrush(ForeColor), new RectangleF(textRect.X, textRect.Y, textRect.Width, textRect.Height), format);
                }
            }
            State.SelectionBufferFrame = buffer;
        }
    }

    internal void CreateHoverFrame(Rectangle rect, Rectangle imageRect, Rectangle textRect)
    {
        if (rect != Rectangle.Empty)
        {
            Image buffer = new Bitmap(rect.Width, rect.Height, PixelFormat.Format32bppArgb);
            using (Graphics g = Graphics.FromImage(buffer)) 
            {
                g.Clear(Color.Transparent);
                g.SmoothingMode = SmoothingMode.HighQuality;
                g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
                g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                Color light = Color.FromArgb(108, 116, 118), dark = Color.FromArgb(108, 116, 118);
                g.FillRectangle(new LinearGradientBrush(rect, light, dark, LinearGradientMode.Vertical), rect);
                if (imageRect != Rectangle.Empty)
                {
                    Image img = AssocImage;
                    if (img != null)
                    {
                        g.DrawImage(img, imageRect);
                    }
                }
                if (!string.IsNullOrEmpty(Text) && textRect != Rectangle.Empty)
                {
                    StringFormat format = new StringFormat();
                    format.Alignment = StringAlignment.Center;
                    format.Trimming = StringTrimming.EllipsisCharacter;
                    g.DrawString(Text, this.Font, new SolidBrush(ForeColor), new RectangleF(textRect.X, textRect.Y, textRect.Width, textRect.Height), format);
                }
            }
            State.HoverBufferFrame = buffer;
        }
    }
    internal void CreateDefaultFrame(Rectangle rect, Rectangle imageRect, Rectangle textRect)
    {
        if (rect != Rectangle.Empty)
        {
            Image buffer = new Bitmap(rect.Width, rect.Height, PixelFormat.Format32bppArgb);
            using (Graphics g = Graphics.FromImage(buffer)) 
            {
                g.Clear(Color.Transparent);
                g.SmoothingMode = SmoothingMode.HighQuality;
                g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
                g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                Color light = Color.Orange, dark = Color.Orange;
                g.FillRectangle(new LinearGradientBrush(rect, light, dark, LinearGradientMode.Vertical), rect);
                if (imageRect != Rectangle.Empty)
                {
                    Image img = AssocImage;
                    if (img != null)
                    {
                        g.DrawImage(img, imageRect);
                    }
                }
                if (!string.IsNullOrEmpty(Text) && textRect != Rectangle.Empty)
                {
                    StringFormat format = new StringFormat();
                    format.Alignment = StringAlignment.Center;
                    format.Trimming = StringTrimming.EllipsisCharacter;
                    g.DrawString(Text, this.Font, new SolidBrush(ForeColor), new RectangleF(textRect.X, textRect.Y, textRect.Width, textRect.Height), format);
                }
            }
            State.DefaultBufferFrame = buffer;

        }
    }
    internal void CreateCloseButtonFrames(Rectangle closeBtnRect)
    {
        if (closeBtnRect != Rectangle.Empty)
        {
            if (ParentTabControl != null && ParentTabControl.CloseButtonImage != null && ParentTabControl.ShowCloseButton) 
            {
                //closeBtnRect
                Image buffer = new Bitmap(closeBtnRect.Width, closeBtnRect.Height, PixelFormat.Format32bppArgb);
                using (Graphics g = Graphics.FromImage(buffer)) 
                {
                    g.Clear(Color.Transparent);
                    g.SmoothingMode = SmoothingMode.HighQuality;
                    g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
                    g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                    g.FillRectangle(new SolidBrush(Color.Transparent), closeBtnRect);
                    g.DrawImage(SetImageOpacity(ParentTabControl.CloseButtonImage, 0.5f), closeBtnRect.X, closeBtnRect.Y, closeBtnRect.Width, closeBtnRect.Height);
                }
                State.DefaultCloseButtonBufferFrame = buffer;

                buffer = new Bitmap(closeBtnRect.Width, closeBtnRect.Height, PixelFormat.Format32bppArgb);
                using (Graphics g = Graphics.FromImage(buffer))
                {
                    g.SmoothingMode = SmoothingMode.HighQuality;
                    g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
                    g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                    g.FillRectangle(new SolidBrush(Color.Transparent), closeBtnRect);
                    g.DrawImage(ParentTabControl.CloseButtonImage, closeBtnRect.X, closeBtnRect.Y, closeBtnRect.Width, closeBtnRect.Height);
                }
                State.FocusedCloseButtonBufferFrame = buffer;

            }                
        }
    }
    /// <summary>  
    /// method for changing the opacity of an image  
    /// </summary>  
    /// <param name="image">image to set opacity on</param>  
    /// <param name="opacity">percentage of opacity</param>  
    /// <returns></returns>  
    private Image SetImageOpacity(Image image, float opacity)
    {
        try
        {
            //create a Bitmap the size of the image provided  
            Bitmap bmp = new Bitmap(image.Width, image.Height);

            //create a graphics object from the image  
            using (Graphics gfx = Graphics.FromImage(bmp))
            {

                //create a color matrix object  
                ColorMatrix matrix = new ColorMatrix();

                //set the opacity  
                matrix.Matrix33 = opacity;

                //create image attributes  
                ImageAttributes attributes = new ImageAttributes();

                //set the color(opacity) of the image  
                attributes.SetColorMatrix(matrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

                //now draw the image  
                gfx.DrawImage(image, new Rectangle(0, 0, bmp.Width, bmp.Height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes);
            }
            return bmp;
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
            return null;
        }
    } 
    #endregion

    #region Constr
    public BackOfficeTabPage() : base() 
    {

    }
    public BackOfficeTabPage(string text)
        : base(text)
    {

    }
    #endregion
}
4

0 回答 0