これはアプリのデザインです:
そして、これは私がスクロールバーを上下に使用したときに起こることです:
チェックボックスはパネル内にあり、パネルは透明(明らか)であり、フォームのみが背景画像を使用します。
なぜその歪みが発生し、どうすれば問題を解決できますか?
PS:さらに情報が必要な場合、またはすべてのフォームなどが必要な場合は、教えてください。
これはアプリのデザインです:
そして、これは私がスクロールバーを上下に使用したときに起こることです:
チェックボックスはパネル内にあり、パネルは透明(明らか)であり、フォームのみが背景画像を使用します。
なぜその歪みが発生し、どうすれば問題を解決できますか?
PS:さらに情報が必要な場合、またはすべてのフォームなどが必要な場合は、教えてください。
一見すると、これは低レベルの調整なしでは不可能に思えます。しかし、私は「ある程度」の回避策を見つけました。
これは、パネルスクロールイベントハンドラー内のC#コードです。
private void panel1_Scroll(object sender, ScrollEventArgs e)
{
panel1.BackColor = System.Drawing.Color.Empty;
panel1.BackColor = System.Drawing.Color.Transparent;
}
このイベントはスクロールバーでのみ機能するため、マウスホイールのスクロールにも同じことを実装する必要があります。VBでは、それは非常に単純で、別の関数を追加するだけです。
これは完全なコードです
Private Sub Panel1_Scroll(sender As Object, e As ScrollEventArgs) Handles Panel1.Scroll
Panel1.BackColor = System.Drawing.Color.Empty
Panel1.BackColor = System.Drawing.Color.Transparent
End Sub
Private Sub Panel1_MouseScroll(sender As Object, e As MouseEventArgs) Handles Panel1.MouseWheel
Panel1.BackColor = System.Drawing.Color.Empty
Panel1.BackColor = System.Drawing.Color.Transparent
End Sub
それでおしまい。これで、スクロールバーとマウスホイールで同じように機能します。
うまくいった解決策は、カスタムパネル(コントロールパネルから継承するクラス)を作成し、スクロールのちらつきを防ぐために使用されるAPI呼び出しLockWindowUpdateおよびOptimizedDoubleBufferプロパティを使用して、再描画をロックするために必要なコードを作成することです。
Public Class MyPanel
Inherits Panel
Public Sub New()
Me.AutoScroll = True
Me.SetStyle(ControlStyles.SupportsTransparentBackColor, True)
Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
End Sub
Private mImage As Image
Public Property Image() As Image
Get
Return mImage
End Get
Set(ByVal value As Image)
mImage = value
Invalidate()
End Set
End Property
Protected Overrides Sub OnScroll(ByVal se As ScrollEventArgs)
If se.Type = ScrollEventType.First Then
LockWindowUpdate(Me.Handle)
ElseIf se.Type = ScrollEventType.ThumbTrack OrElse se.Type = ScrollEventType.ThumbPosition Then
LockWindowUpdate(IntPtr.Zero)
Me.Refresh()
LockWindowUpdate(Me.Handle)
Else
LockWindowUpdate(IntPtr.Zero)
Me.Invalidate()
End If
MyBase.OnScroll(se)
End Sub
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
Console.WriteLine(e.ClipRectangle.ToString())
Using br As New SolidBrush(Me.BackColor)
e.Graphics.FillRectangle(br, Me.ClientRectangle)
End Using
If mImage IsNot Nothing Then
e.Graphics.DrawImage(mImage, 0, 0)
End If
MyBase.OnPaint(e)
End Sub
<DllImport("user32.dll")> _
Private Shared Function LockWindowUpdate(ByVal hWnd As IntPtr) As Boolean
End Function
End Class
Visual Basicの一般的なパネルのようなもので、必要なことを実行するようにプログラムしない限り、パネルのすべてのプロパティを継承します。コントロールバーに「MyPanel」というコントロールのように表示してから、名前を変更する必要があることに注意してください。コントロールとして表示されるようにするには、ソリューションを構築する必要があります。
あなたはフォームと出来上がりをつけて、あなたはそれを使います。
Panelの親であるScrollableControlクラスは、画像を正しく描画するために必要なOnPaintbackground()メソッドをオーバーライドしません。最新のすべてのWindowsバージョンでオンになっている[ドラッグ中にウィンドウの内容を表示する]オプションと組み合わせると、混乱します。
プロジェクトに新しいクラスを追加し、以下に示すコードを貼り付けます。コンパイル。新しいコントロールをツールボックスの上部からフォームにドラッグして、古いコントロールを置き換えます。
using System;
using System.Windows.Forms;
class MyPanel : Panel {
public MyPanel() {
this.DoubleBuffered = true;
}
protected override void OnPaintBackground(PaintEventArgs e) {
if (this.BackgroundImage != null) {
e.Graphics.TranslateTransform(this.AutoScrollPosition.X, this.AutoScrollPosition.Y);
e.Graphics.Clear(this.BackColor);
e.Graphics.DrawImage(this.BackgroundImage, 0, 0);
}
else base.OnPaintBackground(e);
}
}