【发布时间】:2013-03-05 01:28:35
【问题描述】:
我创建了一个继承自 ListBox 的自定义多行 ListBox 控件。在表单中,ListBox 位置位于 ElementHost 中托管的 WPF 圆形透明面板上方。现在,我想要的是 ListBox 背景色是透明的。显然,这在 Winforms 中是不允许的,ListBox 不能是透明的。然后,我尝试了一些东西,但总是有问题。
我想要实现的是:
如您所见,这非常有效,但实际上我遇到了两个问题。
我首先得到的是当我选择一个项目时。字母变得非常难看。只需将下一张图片与第一张图片进行比较。你可以看到它们看起来都很丑,因为它们都被选中了。
我遇到的第二个问题是当我向下/向上滚动 ListBox 时。透明的颜色消失了,我得到了黑色。
我记得在表单中使用可滚动面板时遇到了这个问题。面板是透明的,解决方法是在面板滚动事件中调用 Invalidate() 方法。但我在 ListBox 中没有那个事件。
另外,我想隐藏滚动条但可以滚动。
我附上了 CustomListBox 代码,这样你就可以看到我做了什么。如果你也想要一个简单的多行 ListBox,你可以随意使用它。
以防万一,我将 ListBox 设置为透明的方式是重写 CreateParams。
公共类 MultiLineListBox : System.Windows.Forms.ListBox { 公共多线列表框() { 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 来工作。但是更不可取,因为我不仅遇到了与其他解决方案相同的问题,而且没有显示文本,所以我坚持第一个解决方案。
希望有人能帮帮我!
【问题讨论】:
-
winforms 不支持这些。您已经在使用
ElementHost,为什么不直接创建一个带有适当ItemTemplate和带有透明胶片的漂亮Style的WPF ListBox?...您需要0 行C# 代码和大约10 到20 行XAML为了在 WPF 中做到这一点。 -
@HighCore 是否可以在 Winforms 中做很多事情。只是更复杂。我知道我可以在 WPF 上更轻松地做到这一点,但我对此知之甚少。列表框将为每个项目提供一个上下文菜单。所有这些要求都让我远离 WPF。
-
ContextMenu只是List<ICommand>的图形表示。我不明白这有多复杂。 WPF 中的一切都更容易,而且性能也更好。当你完成这个 winforms 应用程序时,你会意识到它由于性能不佳而无法使用,并且无论如何都必须完全在 WPF 中重新做。 -
另外,我对
"technology or framework ABC supports XYZ"的想法是,您可以在正常时间内使用 ABC 实现 XYZ,而无需求助于一堆 HACKS(例如必须调用非托管代码只是为了做一些事情UI相关的东西)。因此,winforms 不支持任何这些东西。国际海事组织。 -
@HighCore Winform 很慢,它与 Interop with WPF 无关。正如我告诉你的,我对 WPF 知之甚少。这就是我使用 Winforms 的原因。因为我知道。该应用程序几乎完成。我无法将所有这些都迁移到我不掌握的技术中。
标签: c# winforms listbox custom-controls transparent