Custom ListBox with transparent backcolor issue

旧时模样 提交于 2019-12-25 01:55:18

问题


I created a custom multiline ListBox control inherited from ListBox. In the form, the ListBox position is above a WPF rounded and transparent panel hosted in an ElementHost. Now, what I want, is that ListBox backcolor to be transparent. Obviously, this is not allowed in Winforms, a ListBox cant be transparent. Then, I have tried some things, but there is always an issue.

What I want to achieve is this:

As you can see, this works perfectly, but actually I´m having two problems.

The first I get is when I select an item. The letters became pretty ugly. Just compare the next image with the first one. You can see all of them looks ugly because all of them were selected.

The second problem I have, is when I scroll down/up the ListBox. The transparent color just dissapears and I get a black color.

I remember getting this issue with a scrollable panel in a Form. The panel was transparent and the way to solve it was to call Invalidate() method in the panel Scroll event. But I don´t have that event in the ListBox.

Also, I want to hide the scrollbar but to be scrollable.

I attach the CustomListBox code so you can see what I have done. You are free to take it if you want a simple multiline ListBox too.

Just in case, the way that I used to set the ListBox to transparent, was by overriding CreateParams.

public class MultiLineListBox : System.Windows.Forms.ListBox { public MultiLineListBox() { this.DrawMode = DrawMode.OwnerDrawVariable; this.ScrollAlwaysVisible = true; }

    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.ExStyle |= 0x20; // WS_EX_TRANSPARENT
            return cp;
        }
    }

    protected override void OnMeasureItem(MeasureItemEventArgs e)
    {
        if(Site!=null)
            return;
        if(e.Index > -1)
        {
            string s = Items[e.Index].ToString();
            SizeF sf = e.Graphics.MeasureString(s,Font,Width);
            int htex = (e.Index==0) ? 15 : 10;
            e.ItemHeight = (int)sf.Height + htex;           
            e.ItemWidth = Width;
        }
    }

    protected override void OnDrawItem(DrawItemEventArgs e)
    {
        if(Site!=null)
            return;
        if(e.Index > -1)
        {
            string s = Items[e.Index].ToString();                           

            if((e.State & DrawItemState.Focus)==0)
            {
                e.Graphics.DrawString(s,Font,new SolidBrush(Color.White),e.Bounds);             
                e.Graphics.DrawRectangle(new Pen(Color.FromArgb(255, 26, 36, 41)),e.Bounds);                
            }
            else
            {
                e.Graphics.DrawRectangle(new Pen(Color.FromArgb(255, 0, 185, 57)), e.Bounds);
                //e.Graphics.DrawString(s,Font,new SolidBrush(Color.FromArgb(255, 0, 161, 47)),e.Bounds);
            }
        }
    }
}   

Oh, I almost forget. I tried overriding the OnPaintBackGround(), it worked by setting SetStyle to userPaint. But it was even more undesirable, because I was not just having the same problems as the other solution, but also the text was not showed, so, I sticked to the first solution.

Hope somebody can help me out!


回答1:


You could try this...

protected override void OnPaintBackground(PaintEventArgs pevent)
{
    IntPtr hdc = pevent.Graphics.GetHdc();
    Rectangle rect = this.ClientRectangle;
    NativeMethods.DrawThemeParentBackground(this.Handle, hdc, ref rect);
    pevent.Graphics.ReleaseHdc(hdc);
}


internal static class NativeMethods
{
    [DllImport("uxtheme", ExactSpelling = true)]
    public extern static Int32 DrawThemeParentBackground(IntPtr hWnd, IntPtr hdc, ref Rectangle pRect);
}

Its worked for me when I've needed to paint a transparent background color for a control that did not support it. I used it with a TabControl.



来源:https://stackoverflow.com/questions/15207186/custom-listbox-with-transparent-backcolor-issue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!