ToolStripControlHost с иконкой и флажком. Как выделить выделенный предмет? Добавить иконку в поле Иконка?

Я хотел создать Custom ToolStripItem что будет иметь checkbox и значок в нем. Мне удается сделать это, создав пользовательский элемент управления с двумя picturebox и метка. Оставил picturebox если для значка и право действует как особый checkbox добавить позицию в избранное.

Я добавил этот контроль ToolStripControlHost,

  1. Проблема в том, что пробелы слева и справа не нужны, чтобы удалить их или переместить значок в левую строку и удалить правое пространство. Я пытался установить Padding а также Margin значения до 0, но это не работает. Я нашел сообщение с похожей проблемой, но не был правильный ответ. Возможно ли это сделать??

  1. Я хочу сделать выделение всей строки на MouseEnter точно так же, как обычные элементы в ToolStripMenuItem. Когда я переопределяю OnMouseEnter и OnMouseLeave, изменяя свойства фона, он просто меняет цвет размещенного элемента управления, а не antirie ToolStripControlHost. Можно ли имитировать то же поведение, что и ToolStripMenuItem?

Прямо сейчас это выглядит как рисунок "А", и я хочу, чтобы он больше походил на рисунок В, но с флажком в форме звезды:

По сути, я хочу сделать элемент My CustomToolStrip максимально похожим на ToolStripMenuItem. С отдельными событиями для Click (если вы нажимаете на текст) и ChackChange (если вы нажимаете на звезду)

Есть идеи, как это сделать?

Это часть моего кода ToolStripControlHost:

    private void AddEvents()
    {
        this.ToolStripICItemControl.eMouseEnter += new EventHandler(On_MouseEnter);
        this.ToolStripICItemControl.eMouseLeave += new EventHandler(On_MouseLeave);
    }
    private void AutoSizeControl(Control control, int textPadding)
    {
        // Create a Graphics object for the Control.
        Graphics g = control.CreateGraphics();

        // Get the Size needed to accommodate the formatted Text.
        Size preferredSize = g.MeasureString(
           control.Text, control.Font).ToSize();

        // Pad the text and resize the control.
        this.Size = new Size(
           preferredSize.Width + 5 + 50 + (textPadding * 2),
           this.Size.Height /*+ (textPadding * 2)*/ );

        // Clean up the Graphics object.
        g.Dispose();
    }
    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
    }
    protected override void OnSubscribeControlEvents(Control c)
    {
        // Call the base so the base events are connected. 
        base.OnSubscribeControlEvents(c);

        // Cast the control to a  ToolStripCheckBox control.
        ToolStripImageAndCheckBox checkBoxToolStrip = (ToolStripImageAndCheckBox)c;

        // Add the event.
        checkBoxToolStrip.LabelClick += new EventHandler(checkBoxToolStrip_LabelClick);
        checkBoxToolStrip.CheckedChanged += new EventHandler(checkBoxToolStrip_CheckedChanged);
    }
    protected override void OnUnsubscribeControlEvents(Control c)
    {
        // Call the base method so the basic events are unsubscribed. 
        base.OnUnsubscribeControlEvents(c);

        // Cast the control to a ToolStripCheckBox control.
        ToolStripImageAndCheckBox checkBoxToolStrip = (ToolStripImageAndCheckBox)c;

        // Remove the event.
        checkBoxToolStrip.LabelClick -= new EventHandler(checkBoxToolStrip_LabelClick);
    }
    protected override void OnMouseEnter(EventArgs e)
    {
        DefaultBackColor = this.BackColor;
        base.OnMouseEnter(e);
        this.BackColor = Color.Aquamarine;
    }
    protected override void OnMouseLeave(EventArgs e)
    {
        base.OnMouseLeave(e);
        this.BackColor = DefaultBackColor;
    }
    void checkBoxToolStrip_LabelClick(object sender, EventArgs e)
    {
        if (Click != null)
            Click(this, e);
    }
    void checkBoxToolStrip_CheckedChanged(object sender, EventArgs e)
    {
        if (CheckedChange != null)
            CheckedChange(this, e);
    }
    void On_MouseLeave(object sender, EventArgs e)
    {
        OnMouseLeave(e);
        //throw new NotImplementedException();
    }
    void On_MouseEnter(object sender, EventArgs e)
    {
        this.Select();
        this.Focus();
        OnMouseEnter(e);
    }

1 ответ

Решение

Мне удается делать то, что мне нужно, управляя MyControl из ToolStripMenuItem и переопределяя метод onPaint

public class MyControl : ToolStripMenuItem
{
    public MyControl(){}
    public MyControl(string text, Image image ):base (text,image){}
    public MyControl(string text):base(text){}
    public MyControl(Image image):base(image){}
    public MyControl(string text,Image image,EventHandler onClick):base(text,image,onClick){}
    public MyControl(string text, Image image,int id):base(text,image){  this.ID = id;}
    public MyControl(string text,Image image,int id,EventHandler onClick):base(text,image,onClick){this.ID = id; }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);

        if (base.Checked == false)
        {
           Rectangle rect = new Rectangle(this.Width - 20, 1, 20, 20);               
            e.Graphics.DrawImage(Properties.Resources.BlackStar, rect);
        }
        else
        { 
            Rectangle rect = new Rectangle(this.Width - 20, 1, 20, 20);
            e.Graphics.DrawImage(Properties.Resources.YellowStar, rect);
        }
    }
    public int ID { get; set; }
    public bool StarClicked { get; set; }

    protected override void OnMouseDown(MouseEventArgs e)
    {            
        StarClicked = e.X > (this.Width - 20);
        if (StarClicked)
        {
            this.Checked = this.Checked == true ? false : true;
        }
        else
            base.OnClick(e);
        base.OnMouseDown(e);
    }

вот так это выглядит сейчас

https://stackru.com/images/5472003b2c64e80a4e4532802bb17fe089591c6c.png

Код формы:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        AddMenuElements(7);
    }
    public void AddMenuElements(int licznik)
    {
        ToolStripMenuItem wszystkie = new ToolStripMenuItem("wszystkie", SystemIcons.Question.ToBitmap());
        manu1ToolStripMenuItem.DropDownItems.Add(wszystkie);
        menuStrip1.Renderer = new ToolStripSystemRenderer();
        for (int i = 0; i < licznik; i++)
        {
            ToolStripMenuItem element = new ToolStripMenuItem(String.Format("element {0}", i), GetIcon(i),element2_Click);
            element.Visible = i % 2 == 0 ? false:true;                
            manu1ToolStripMenuItem.DropDownItems.Add(element);
        }


        for (int i = 0; i < licznik; i++)
        {
            MyControl element2 = new MyControl(String.Format("element {0}",i), GetIcon(i),element2_Click);
            element2.ID = i;
            element2.CheckedChanged += (s, e) =>
            {                    
                MyControl control = s as MyControl;
                manu1ToolStripMenuItem.DropDownItems[control.ID + 1].Visible = control.Checked;                  
            };
            element2.Checked = i % 2 == 0 ? false : true;

            wszystkie.DropDownItems.Add(element2); 

        }
    }
    void element2_Click(object sender, EventArgs e)
    {
        MyControl kontener = (sender as MyControl);

        if (kontener.ForeColor == Color.Red)
            kontener.ForeColor = Color.Black;
        else
            kontener.ForeColor = Color.Red;

    }
    private static Image GetIcon(int i)
    {
        Image ikona = null;
        switch (i)
        {
            case 0: ikona = SystemIcons.Application.ToBitmap();
                break;
            case 1: ikona = SystemIcons.Asterisk.ToBitmap();
                break;
            case 2: ikona = SystemIcons.WinLogo.ToBitmap();
                break;
            case 3: ikona = SystemIcons.Exclamation.ToBitmap();
                break;
            case 4: ikona = SystemIcons.Hand.ToBitmap();
                break;
            case 5: ikona = SystemIcons.Warning.ToBitmap();
                break;
            default: ikona = SystemIcons.Shield.ToBitmap();
                break;
        }
        return ikona;
    }   
}

В основном это делает то, что я хочу, мне просто нужно, чтобы он не исчезал при нажатии на звездочку. Спасибо за помощь @LarsTech, она подсказала мне, как это сделать.

Другие вопросы по тегам