-1

基本的に、複数の譜表を作成するために、複数のビットマップをそれ自体に描画するパネル クラスの拡張機能を作成しました。パネルに垂直スクロール バーを追加しようとしましたが、うまくいきません。私のペイント手順はこれに似ています

private void StavePanel_Paint(object sender, PaintEventArgs e)
{
    for(int i = 0; i < linenumber; i++)
    {
        Bitmap bmp = new Bitmap(Width, 200);
        //edit bmp to resemble stave
        e.Graphics.DrawImage(bmp,new Point(0,200*i);
    }
}
4

4 に答える 4

1

AutoScrollMinSize プロパティを設定するだけです。

panel1.AutoScrollMinSize = new Size(0, 1000);

ペイント イベント中に、TranslateTransform メソッドを使用して、描画の位置を変換する必要があります。また、描画後にビットマップを破棄する必要があります。

e.Graphics.TranslateTransform(panel1.AutoScrollPosition.X, panel1.AutoScrollPosition.Y);

using (Bitmap bmp = new Bitmap(Width, 200)) {
  //edit bmp to resemble stave
  e.Graphics.DrawImage(bmp,new Point(0,200*i);
}

または、事前に作成して保存し、ペイント イベント中のコストを回避します。

于 2015-10-06T19:10:37.430 に答える
0

AutoScroll他の人が述べたように、 trueに設定する必要があります。しかしその後、AutoScrollMinSizeビットマップを追加または削除するときはいつでも(または固定されている場合は最初に)、式を使用して高さを設定する必要がありますbitmapCount * bitmapHeight。また、ペイント ハンドラーでは、プロパティを考慮する必要がありAutoScrollPosition.Yます。

以下は、実際のコンセプトの小さな例です。

using System;
using System.Drawing;
using System.Windows.Forms;

namespace Tests
{
    static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            var form = new Form();
            var panel = new Panel { Dock = DockStyle.Fill, Parent = form };
            // Setting the AutoScrollMinSize
            int bitmapCount = 10;
            int bitmapHeight = 200;
            panel.AutoScrollMinSize = new Size(0, bitmapCount * bitmapHeight);
            panel.Paint += (sender, e) =>
            {
                // Considering the AutoScrollPosition.Y
                int offsetY = panel.AutoScrollPosition.Y;
                var state = offsetY != 0 ? e.Graphics.Save() : null;
                if (offsetY != 0) e.Graphics.TranslateTransform(0, offsetY);
                var rect = new Rectangle(0, 0, panel.ClientSize.Width, bitmapHeight);
                var sf = new StringFormat(StringFormat.GenericTypographic) { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center };
                for (int i = 0; i < bitmapCount; i++)
                {
                    // Your bitmap drawing goes here
                    e.Graphics.FillRectangle(Brushes.Yellow, rect);
                    e.Graphics.DrawRectangle(Pens.Red, rect);
                    e.Graphics.DrawString("Bitmap #" + (i + 1), panel.Font, Brushes.Blue, rect, sf);
                    rect.Y += bitmapHeight;
                }
                if (state != null) e.Graphics.Restore(state);
            };
            Application.Run(form);
        }
    }
}

編集: LarsTechがコメントAutoScrollで正しく言及したように、この場合、プロパティを設定する必要はありません。他のすべては同じままです。

于 2015-10-06T19:38:42.800 に答える
0

GDI コードを呼び出してコントロールを描画する既存のパターンを引き続き使用する場合は、スクロールバー コントロールを追加し、イベント ハンドラーをその変更イベントに追加する必要があります。.Invalidate変更ハンドラーは、パネルで呼び出す以外に何もする必要はありません。.Invalidate は、「ダーティ」であり、再描画する必要があることをコントロールに通知します。スクロールバーの値の逆方向に描画をオフセットするには、描画コードを変更する必要があります。

したがって、スクロールバーが 50 の位置にある場合、すべてを Y - 50 に描画する必要があります。

純粋な GDI 描画コードを使用している場合、AutoScroll プロパティをいじる必要はまったくありません。これは、パネルがパネルよりも大きい実際のコントロールをホストしている場合にのみ使用されます。

于 2015-10-06T19:04:18.840 に答える
0

AutoScrollプロパティを true に設定します。

代替案を検討することもできます。

  • FlowLayoutPanelペイントする代わりに PictureBoxes を動的に追加します。
  • TableLayoutPanelペイントする代わりに PictureBoxes を動的に追加します。
  • プロパティを拡張してorListBoxに設定し、メソッドandをオーバーライドします( のみ)。DrawModeOwnerDrawFixedOwnerDrawVariableOnPaintOnMeasureItemOwnerDrawVariable
于 2015-10-06T18:51:06.330 に答える