我创建了一个从ListBox继承的自定义多行ListBox控件。在表单中,ListBox位置位于ElementHost中托管的WPF圆形透明面板上方。现在,我想要的是,ListBox背景颜色是透明的。显然,Winforms不允许这样做,ListBox不能透明。然后,我尝试了一些事情,但总有一个问题。
我想要实现的目标是:
正如你所看到的,这很有效,但实际上我有两个问题。
我得到的第一个是当我选择一个项目时。这些信件变得非常难看。只需将下一个图像与第一个图像进行比较。你可以看到所有这些都看起来很难看,因为所有这些都被选中了。
我遇到的第二个问题是当我向下/向上滚动ListBox时。透明的颜色消失了,我变成了黑色。
我记得在表单中使用可滚动面板来解决此问题。该面板是透明的,解决它的方法是在面板Scroll事件中调用Invalidate()方法。但我在ListBox中没有那个事件。
另外,我想隐藏滚动条但可以滚动。
我附加了CustomListBox代码,这样你就可以看到我做了什么。如果你想要一个简单的多行ListBox,你也可以随意使用它。
以防万一,我用来将ListBox设置为透明的方式是覆盖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);
}
}
}
}
哦,我差点忘了。我尝试重写OnPaintBackGround(),它通过将SetStyle设置为userPaint来工作。但这更不可取,因为我不只是遇到与其他解决方案相同的问题,而且文本没有显示,所以,我坚持第一个解决方案。
希望有人可以帮助我!
答案 0 :(得分:1)
你可以试试这个......
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。