ListBox から継承されたカスタムの複数行 ListBox コントロールを作成しました。フォームでは、ListBox の位置は、ElementHost でホストされている WPF の丸みを帯びた透明なパネルの上にあります。今、私が欲しいのは、ListBox の背景色を透明にすることです。明らかに、これは Winforms では許可されていません。ListBox を透明にすることはできません。それから、私はいくつかのことを試しましたが、常に問題があります。
私が達成したいのはこれです:
ご覧のとおり、これは完全に機能しますが、実際には 2 つの問題があります。
最初に取得するのは、アイテムを選択したときです。文字がかなり醜くなりました。次の画像と最初の画像を見比べてみてください。それらのすべてが選択されているため、それらのすべてが醜いように見えることがわかります。
私が抱えている2番目の問題は、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 に設定することで機能しました。しかし、他の解決策と同じ問題を抱えているだけでなく、テキストが表示されなかったため、さらに望ましくなかったので、最初の解決策に固執しました。
誰かが私を助けてくれることを願っています!