具有透明背景色问题的自定义列表框 [英] Custom ListBox with transparent backcolor issue

查看:66
本文介绍了具有透明背景色问题的自定义列表框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个继承自ListBox的自定义多行ListBox控件.在表单中,ListBox位置在ElementHost中承载的WPF圆形透明面板上方.现在,我想要的是ListBox背景色是透明的.显然,在Winforms中不允许这样做,因为ListBox不能透明.然后,我尝试了一些事情,但始终存在问题.

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.

我想实现的是这样:

如您所见,这很好用,但实际上我有两个问题.

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.

我记得在Form中使用可滚动面板会遇到此问题.该面板是透明的,解决该问题的方法是在面板Scroll事件中调用Invalidate()方法.但是我在ListBox中没有该事件.

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.

我附上了CustomListBox代码,以便您可以看到我所做的事情.如果您也想要一个简单的多行ListBox,则可以随意使用它.

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.

以防万一,我以前用来将ListBox设置为透明的方式是通过覆盖CreateParams.

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

公共类MultiLineListBox:System.Windows.Forms.ListBox { 公共MultiLineListBox() { this.DrawMode = DrawMode.OwnerDrawVariable; this.ScrollAlwaysVisible = true; }

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);
            }
        }
    }
}   

哦,我几乎忘记了.我尝试覆盖OnPaintBackGround(),它通过将SetStyle设置为userPaint来工作.但是,这甚至更不可取,因为我不仅遇到了与其他解决方案相同的问题,而且没有显示文本,因此,我坚持第一个解决方案.

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.

希望有人可以帮助我!

推荐答案

您可以尝试...

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);
}

当我需要为不支持它的控件绘制透明的背景色时,它对我有用.我将它与TabControl一起使用.

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.

这篇关于具有透明背景色问题的自定义列表框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆