0

this is for Winforms / C# btw.

So I am making my own ComboBox, just playing around. The item List is basically a Panel, which is located under or above the ComboBox control, depending on its height and location.

This works as intended, as long as I use AnchorStyle Top / Left for my usercontrol. enter image description here

As soon as I switch to Top / Right Style, the location of my listpanel breaks. Okay, makes sense, the location point of my usercontrol changes with the different anchorstyle, so how about I adjust my panel to a new location using my usercontrol.LocationChanged event? Doesen't work. Maybe because of the order of the events? Or does the origin of locations change depending on the given AnchorStyles?

Anyway, I am a bit lost. Unfortunately I couldn't find a similar case here, therefore this question.

Here's my DropDownPanel (effectively my "list"):

    private Panel DropDownPanel()
    {
        Panel DropDownPanel = new Panel() {
            Width = this.Width,
            Height = 200,
            BackColor = _skin.TextBoxBackColor,
            BorderStyle = BorderStyle.FixedSingle,
            ForeColor = _skin.TextBoxForeColor,
            Visible = false,
            AutoScroll = false
        };
        DropDownPanel.HorizontalScroll.Enabled = false;
        DropDownPanel.HorizontalScroll.Visible = false;
        DropDownPanel.HorizontalScroll.Maximum = 0;
        DropDownPanel.AutoScroll = true;
        DropDownPanel.Leave += DropDownPanel_Leave;
        return DropDownPanel;
    }

Here's my userControl Load Event:

    private void GbComboBox_Load(object sender, EventArgs e)
    {
        _dropDownPanel = DropDownPanel();
        this.Parent.Parent.Controls.Add(_dropDownPanel);
        RelocateDropDownPanel();
        _dropDownPanel.BringToFront();
        ApplyItems(_items);
    }

And my calculation for the location:

    private void RelocateDropDownPanel()
    {
        if (_dropDownPanel != null)
        {
            int initLocY = this.Parent.Location.Y + this.Location.Y + this.Height + _dropDownPanel.Height;
            int fullHeight = this.FindForm().Height;
            Point p = new Point();
            if (initLocY < fullHeight)
            {
                 p = new Point(this.Parent.Location.X + this.Location.X, initLocY - _dropDownPanel.Height);
            }
            else
            {
                p = new Point(this.Parent.Location.X + this.Location.X, initLocY - _dropDownPanel.Height - this.Height);
            }
            _dropDownPanel.Location = p;
        }
    }
arvenyon
  • 153
  • 1
  • 8
  • 2
    Wouldn't it be simpler to owner-draw a standard ComboBox? You'll have more problem than just find the *right position*. How about the limits imposed by the Parent of your Combo (and the container itself) to the visibility of the Panel? And when the Parent changes? (Many more...) – Jimi Sep 01 '20 at 13:20
  • @Jimi you are completely right, and I am aware of that. But I would like to put alternative ways aside for a moment, even though I really appreciate them! – arvenyon Sep 01 '20 at 13:24
  • Start from here: `this.Parent.Parent.Controls.Add(_dropDownPanel);`. This is of course wrong. You need to handle the re-locations of your ComboBox (`LocationChanged`, `Resize`, `SizeChanged` etc.) and `PointToScreen()` - `PointToClient()` the new location of the List-Panel. The Parent of the List-Panel can be the Form (or the Desktop, see if you can get this to work, it's fun :). After that, the anchors are not exactly your big problem. – Jimi Sep 01 '20 at 13:33

1 Answers1

0

So I figured out a "solution". I simply inherited the Anchor of my Panel from the Usercontrol it was associated to.

But I wanna mention, that still, this whole thing is kind of a crappy way of dealing with custom combobox desings. As @Jimi stated in his first comment, the correct way of doing this would be to ownerdraw the combobox. I haven't done this because of specific reasons, which didn't let me do this.

A little example on how this could be made:

Change ComboBox Border Color in Windows Forms

arvenyon
  • 153
  • 1
  • 8