0

I'm having a weird behavior with a class I created inheriting from PictureBox.

It's a class made to behave like a button (basically what I care about is the mouse enter, mouse leave, mouse down, mouse up events).

Everything works perfectly until I add the TextLabel (code below) to the control of my customized class. It shows the label, centered and everything as I wanted, but the events I mentioned before (and every other event in that matter) becomes disabled, for some reason it won't fire them.

I would like to know what is the reason for that behavior and if there is any fix for it.

public class RoundedButton : PictureBox
{
    private readonly Image r_BasicImage =  RoundedButtonCheck2.Properties.Resources.basicRoundedButtonIcon as Image;
    private readonly Image r_HoverImage = RoundedButtonCheck2.Properties.Resources.hoverRoundedButtonIcon as Image;
    private readonly Image r_ClickImage = RoundedButtonCheck2.Properties.Resources.clickRoundedButtonIcon as Image;

    private string m_Text;
    private Font m_Font;
    public Color m_TextColor;
    private Label LabelText = new Label();


    public RoundedButton()
    {
        this.Width = 130;
        this.Height = 40;
        this.Image = r_BasicImage;
        this.BackColor = Color.Transparent;
        this.SizeMode = PictureBoxSizeMode.StretchImage;
        this.MouseDown += RoundedButton_MouseDown;
        this.MouseUp += RoundedButton_MouseUp;
        this.MouseEnter += RoundedButton_MouseEnter;
        this.MouseLeave += RoundedButton_MouseLeave;
        LabelText.Font = ButtonFont;
        ButtonTextColor = Color.Black;
        //PROBLEMATIC CODE HERE:
        ***********this.Controls.Add(LabelText);***************
    }

    public Color ButtonTextColor
    {
        get
        {
            return m_TextColor;
        }
        set
        {
            m_TextColor = value;
            LabelText.ForeColor = m_TextColor;
        }
    }
    public Font ButtonFont
    {
        get
        {
            if (m_Font == null)
            {
                m_Font = new Font("Calibri Light", 12);
            }
            return m_Font;
        }
        set
        {
            m_Font = value;
            LabelText.Font = ButtonFont;
            adjustLabel();
        }
    }

    public string ButtonText
    {
        get
        {
            return m_Text;
        }
        set
        {

            m_Text = value;
            LabelText.Text = m_Text;
            adjustLabel();
        }
    }
    private void adjustLabel()
    {
        const int MARGIN = 10;
        LabelText.AutoSize = true;//needed for autosize calculation of the label;
        Size newSize = new Size(LabelText.Size.Width, LabelText.Size.Height); ;
        LabelText.AutoSize = false;//after auto-calculated size of the label, set to false in order for centering label works well.
        this.MinimumSize = newSize;
        this.Size = new Size(newSize.Width + MARGIN, newSize.Height + MARGIN);
        LabelText.TextAlign = ContentAlignment.MiddleCenter;
        LabelText.Dock = DockStyle.Fill;
    }

    private void RoundedButton_MouseLeave(object sender, EventArgs e)
    {
        RoundedButton hoveredButton = sender as RoundedButton;
        if (hoveredButton != null)
        {
            hoveredButton.Image = r_BasicImage;
            hoveredButton.SizeMode = PictureBoxSizeMode.StretchImage;
        }
    }

    private void RoundedButton_MouseEnter(object sender, EventArgs e)
    {
        RoundedButton hoveredButton = sender as RoundedButton;
        if (hoveredButton != null)
        {
            hoveredButton.Image = r_HoverImage;
            hoveredButton.SizeMode = PictureBoxSizeMode.StretchImage;
        }
    }

    private void RoundedButton_MouseUp(object sender, MouseEventArgs e)
    {
        RoundedButton clickedButton = sender as RoundedButton;
        if (clickedButton != null)
        {
            clickedButton.Image = r_BasicImage;
            clickedButton.SizeMode = PictureBoxSizeMode.StretchImage;

        }
    }

    private void RoundedButton_MouseDown(object sender, MouseEventArgs e)
    {
        RoundedButton clickedButton = sender as RoundedButton;
        if (clickedButton != null)
        {
            clickedButton.Image = r_ClickImage;
            clickedButton.SizeMode = PictureBoxSizeMode.StretchImage;

        }
    }
}
mkrieger1
  • 19,194
  • 5
  • 54
  • 65
tom01
  • 76
  • 3
  • 1
    Quick guess: `LabelText` is gobbling up the events before `RoundedButton` can see them. – MikeH Nov 12 '18 at 23:50
  • if so, any work-around or fix? – tom01 Nov 12 '18 at 23:57
  • 1
    Try subscribing `LabelText` to those same events, see if it works then. – MikeH Nov 13 '18 at 00:00
  • yea, it does works (from within the class). your guess was correct, yet its not a fix, first because it feels a bit upside-down, second because components that will use RoundedButton wont be able to subscribe to its events since the TextLabel is private and i dont wont it to be public... – tom01 Nov 13 '18 at 00:16
  • You could just call the `OnMouseDown` method from the event of your label which will fire the `MouseDown` event that is public. I'm not sure there's a way to prevent the `LabelText` from eating up the events (I could be wrong though). – MikeH Nov 13 '18 at 00:22
  • _yet its not a fix, first because it feels a bit upside-down_ It is perfectly fine. _second because components that will use RoundedButton wont be able to subscribe to its events_ They shouldn't need to since they will fire as you have already subscribed to them. Note: You subscribe to the __very same__ events! So, there is no diference. Make them public or, better yet, let them call public functions you can override in the derived classes. – TaW Nov 13 '18 at 14:39

0 Answers0