カスタム描画されたドキュメントキャンバスをズームするカスタムコントロールがあります。ScrollableControlをAutoScrollをfalseに設定して使用する方法
AutoScrollを使用しようとしましたが、満足のいく結果が得られませんでした。 AutoScrollPositionとAutoScrollMinSizeを(任意の順序で)バック・ツー・バックに設定すると、ペイントが強制され、ズームが変化するたびにジッタが発生します。これは、両方のプロパティを変更したときにUpdateを呼び出していてInvalidateではなかったためです。
ズームレベルまたはクライアントのサイズの変更、私は今、手動でその都度のような偽に自動スクロールセットとHorizontalScrollとVerticalScrollプロパティを設定しています。この場合
int canvasWidth = (int)Math.Ceiling(Image.Width * Zoom) + PageMargins.Horizontal;
int canvasHeight = (int)Math.Ceiling(Image.Height * Zoom) + PageMargins.Vertical;
HorizontalScroll.Maximum = canvasWidth;
HorizontalScroll.LargeChange = ClientSize.Width;
VerticalScroll.Maximum = canvasHeight;
VerticalScroll.LargeChange = ClientSize.Height;
if (canvasWidth > ClientSize.Width)
{
HorizontalScroll.Visible = true;
}
else
{
HorizontalScroll.Visible = false;
HorizontalScroll.Value = 0;
}
if (canvasHeight > ClientSize.Height)
{
VerticalScroll.Visible = true;
}
else
{
VerticalScroll.Visible = false;
VerticalScroll.Value = 0;
}
int focusX = (int)Math.Floor((FocusPoint.X * Zoom) + PageMargins.Left);
int focusY = (int)Math.Floor((FocusPoint.Y * Zoom) + PageMargins.Top);
focusX = focusX - ClientSize.Width/2;
focusY = focusY - ClientSize.Height/2;
if (focusX < 0)
focusX = 0;
if (focusX > canvasWidth - ClientSize.Width)
focusX = canvasWidth - ClientSize.Width;
if (focusY < 0)
focusY = 0;
if (focusY > canvasHeight - ClientSize.Height)
focusY = canvasHeight - ClientSize.Height;
if (HorizontalScroll.Visible)
HorizontalScroll.Value = focusX;
if (VerticalScroll.Visible)
VerticalScroll.Value = focusY;
、FocusPointがありますユーザーがフォーカスしているビットマップの座標を保持するPointF構造体(たとえば、マウスホイールをズームインすると、その時点で現在のマウスの位置にフォーカスしている)。この機能はほとんどの場合機能します。
スクロールバーは機能しません。ユーザーがいずれかのスクロールバーをクリックして手動でスクロールしようとすると、両方とも0に戻り続けます。コード内のどこにでも設定しません。
if (se.ScrollOrientation == ScrollOrientation.VerticalScroll)
{
VerticalScroll.Value = se.NewValue;
}
else
{
HorizontalScroll.Value = se.NewValue;
}
Invalidate();
しかし、これはフリックや範囲外のスクロールなど、いくつかの非常に不安定動作が発生します。私はOnScroll()メソッドで次のように書いて試してみました。
OnScrollのコードをどのように記述する必要がありますか?私はbase.OnScrollを試しましたが、AutoScrollがfalseに設定されている間は何もしませんでした。
初めての方がいいと思います。最初にAutoScrollMinSizeを設定してから、AutoScrollPositionを呼び出します。フリッカーを制御するには、ダブルバッファーパネルを使用します。 – LarsTech
私のコントロールはダブルバッファーされていました。 AutoScrollMinSizeとAutoScrollPositionの両方を同時に変更する場合を除き、決して点滅しませんでした。 –