C# 如何使ListBox的背景透明?

C# 如何使ListBox的背景透明?,c#,winforms,listbox,backcolor,C#,Winforms,Listbox,Backcolor,我有一个以图片为背景的c#WinForms应用程序。我在窗口中放置了一个列表框,我想将背景色更改为对我的列表框透明。但是列表框不支持透明的背景色。我能为它做些什么?你能做的应该是: 比如说,我们想要创建一个名为TansparentListBox的透明列表框。因此,我们需要从ListBox控件派生一个新类,设置一些控件样式使其具有双缓冲,防止绘制背景,并说我们将自己绘制: using System; using System.Drawing; using System.Runtime.Intero

我有一个以图片为背景的c#WinForms应用程序。我在窗口中放置了一个列表框,我想将
背景色
更改为对我的列表框透明。但是列表框不支持透明的背景色。我能为它做些什么?

你能做的应该是:

比如说,我们想要创建一个名为
TansparentListBox
的透明列表框。因此,我们需要从
ListBox
控件派生一个新类,设置一些控件样式使其具有双缓冲,防止绘制背景,并说我们将自己绘制:

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.ComponentModel;

[ToolboxBitmap(typeof(ListBox)),
    DesignerCategory("")]
public class TransparentListBox : ListBox
{

    public TransparentListBox() : base()
    {
        SetStyle(
            ControlStyles.Opaque |
            ControlStyles.AllPaintingInWmPaint |
            ControlStyles.ResizeRedraw |
            ControlStyles.UserPaint |
            ControlStyles.OptimizedDoubleBuffer, true);
        DrawMode = DrawMode.OwnerDrawFixed;
    }
    //...
现在,我们需要覆盖
OnPaint
OnDrawItem
事件来进行绘图。该函数用于复制父对象的背景,仅复制控件的区域。此外,我们还有一个新成员,
SelectionBackColor
属性,即所选项目的背景色:

/。。。
公共颜色选择backcolor{get;set;}=Color.DarkOrange;
[DllImport(“uxtheme”,ExactSpelling=true)]
私有外部静态int-DrawThemeParentBackground(
IntPtr hWnd,
IntPtr hdc,
参考矩形预制件
);
受保护的覆盖无效OnPaint(PaintEventArgs e)
{
var g=e.图形;
var rec=ClientRectangle;
IntPtr hdc=g.GetHdc();
绘制部件背景(this.Handle、hdc、ref-rec);
g、 释放hdc(hdc);
使用(Region reg=新区域(例如ClipRectangle))
{
如果(Items.Count>0)
{
对于(int i=0;i
困难的部分已经完成了。要完成此操作,应在发生某些事件时刷新图形,否则将导致视觉混乱:

/。。。
受保护的覆盖无效OnSelectedIndexChanged(EventArgs e)
{
基础。根据所选指标变更(e);
使无效();
}
MouseEventArgs e上的受保护覆盖无效(MouseEventArgs e)
{
base.OnMouseDown(e);
使无效();
}
MouseWheel上的受保护覆盖无效(MouseEventArgs e)
{
底轮(e);
使无效();
}
//...
此外,当同时使用垂直和水平滚动条时,需要刷新。由于ListBox控件没有任何滚动事件,因此可以通过重写
WndProc
来执行此操作

/。。。
私有常量int WM_KILLFOCUS=0x8;
私有常量int WM_VSCROLL=0x115;
私有常量int wmhscroll=0x114;
受保护的覆盖无效WndProc(参考消息m)
{
如果(m.Msg!=WM_KILLFOCUS&&
(m.Msg==WM|HSCROLL | m.Msg==WM|VSCROLL))
使无效();
基准WndProc(参考m);
}
}
就这样。拼图、重建和尝试


你能做的应该是:

比如说,我们想要创建一个名为
TansparentListBox
的透明列表框。因此,我们需要从
ListBox
控件派生一个新类,设置一些控件样式使其具有双缓冲,防止绘制背景,并说我们将自己绘制:

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.ComponentModel;

[ToolboxBitmap(typeof(ListBox)),
    DesignerCategory("")]
public class TransparentListBox : ListBox
{

    public TransparentListBox() : base()
    {
        SetStyle(
            ControlStyles.Opaque |
            ControlStyles.AllPaintingInWmPaint |
            ControlStyles.ResizeRedraw |
            ControlStyles.UserPaint |
            ControlStyles.OptimizedDoubleBuffer, true);
        DrawMode = DrawMode.OwnerDrawFixed;
    }
    //...
现在,我们需要覆盖
OnPaint
OnDrawItem
事件来进行绘图。该函数用于复制父对象的背景,仅复制控件的区域。此外,我们还有一个新成员,
SelectionBackColor
属性,即所选项目的背景色:

/。。。
公共颜色选择backcolor{get;set;}=Color.DarkOrange;
[DllImport(“uxtheme”,ExactSpelling=true)]
私有外部静态int-DrawThemeParentBackground(
IntPtr hWnd,
IntPtr hdc,
参考矩形预制件
);
受保护的覆盖无效OnPaint(PaintEventArgs e)
{
var g=e.图形;
var rec=ClientRectangle;
IntPtr hdc=g.GetHdc();
绘制部件背景(this.Handle、hdc、ref-rec);
g、 释放hdc(hdc);
使用(Region reg=新区域(例如ClipRectangle))
{
如果(Items.Count>0)
{
对于(int i=0;i