0

これはアプリのデザインです:

ここに画像の説明を入力してください

そして、これは私がスクロールバーを上下に使用したときに起こることです:

ここに画像の説明を入力してください

チェックボックスはパネル内にあり、パネルは透明(明らか)であり、フォームのみが背景画像を使用します。

なぜその歪みが発生し、どうすれば問題を解決できますか?

PS:さらに情報が必要な場合、またはすべてのフォームなどが必要な場合は、教えてください。

4

3 に答える 3

2

一見すると、これは低レベルの調整なしでは不可能に思えます。しかし、私は「ある程度」の回避策を見つけました。

  1. パネルにOnScrollイベントを作成する
  2. 背景色(黒など)を使用して再描画し、再度透明に設定します

これは、パネルスクロールイベントハンドラー内の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

それでおしまい。これで、スクロールバーとマウスホイールで同じように機能します。

于 2012-11-22T16:43:28.643 に答える
2

うまくいった解決策は、カスタムパネル(コントロールパネルから継承するクラス)を作成し、スクロールのちらつきを防ぐために使用される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」というコントロールのように表示してから、名前を変更する必要があることに注意してください。コントロールとして表示されるようにするには、ソリューションを構築する必要があります。

あなたはフォームと出来上がりをつけて、あなたはそれを使います。

于 2012-11-24T14:14:00.310 に答える
1

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);
    }
}
于 2012-11-22T17:48:10.120 に答える