0

こんにちは、ばかげた質問かもしれませんが、ここで問題を理解することはできません。フォームに単一のブロックを入力するためのコードは次のとおりです。

    private void drawBackground()
{
    Graphics g = genPan.CreateGraphics();
    Image Block = Image.FromFile(@"C:\Users\Administrator\Desktop\movment V1\movment V1\images\BrownBlock.png");
    float recWidth = Block.Width; 
    // rectangle width didnt change the name from previous code, it's picture width.

    float recHeight = Block.Height;
    // rectangle Heightdidnt change the name from previous code, it's picture Height.

    float WinWidth = genPan.Width; // genPan is a panel that docked to the form

    float WinHeight = genPan.Height;

    float curWidth = 0; //indicates where the next block will be placed int the X axis
    float curHeight = 0;//indicates where the next block will be placed int the Y axis

    while ((curHeight + recHeight) <= WinHeight)
    {
        if (curWidth >= WinWidth / 3 || curWidth <= WinWidth / 1.5 ||
            curHeight >= WinHeight / 3 || curHeight <= WinHeight / 1.5)
        {
            g.DrawImage(Block, curWidth, curHeight, recWidth , recHeight );
        }
        curWidth += recWidth;
        if ((WinWidth - curWidth) < recWidth)
        {
            curWidth = 0;
            curHeight += 50;
        }
    }
}

ボタンからこの関数を起動すると、完全に正常に機能します。しかし、InitializeComponent()の後にfuncを起動するとします。コンストラクターのメソッドまたはFORMで表示されるイベントで、ボタンがまだフォーム上にある間、関数は実行されますが、ブロックの背景は表示されませんが、灰色は表示されます。しかし、ボタンを削除すると、背景が表示されます。= \

なぜそれが起こっているのか、それを修正する方法、そして私が間違っていることを理解することはできません..誰かが説明してもらえますか..?

4

2 に答える 2

1

何らかの条件/アクション/ユーザー操作に基づいて背景のみを描画する必要がある場合...

この機能への呼び出しをフォームの OnPaint メソッドに入れ、いくつかのボリアン変数が に等しい場合 にのみtrue有効にします。そして、そのブール値は、ボタンをクリックしたときにのみ真になります。

仮定の例:

protected override OnPaint(...) //FORMS ONPAINT OVERRIDE
{
    if(needBackGround) //INITIAL VALUE AT STARTUP IS FALSE
       drawBackground(); 
} 

public void ButtonClickHandler(...)
{
    needBackGround= !needBackGround;  //INVERSE THE VALUE OF BOOLEAN
}

これは明らかに、実際のコードではなく、ヒントを提供する単なるスニペットです。ちらつき、サイズ変更の処理、パフォーマンスなど、直面する必要がある他の問題がある可能性がありますが、これは開始点にすぎません。

于 2013-01-17T11:12:58.070 に答える
1

現在のロジックを使用して実際にそれを行うことはできません。問題は、コントロール (このgenPan場合はパネル) に独自の Paint イベントがあり、呼び出されると、使用したグラフィックを上書きすることです。

ボタンをクリックして描画しても、フォームが再描画されるまでしか機能しません。たとえば、他のウィンドウにフォーカスしてフォームに再度フォーカスしてみてください。描画したものは失われます。

そのようなことを行う適切な方法は、いくつかの基本的なコントロール (あなたの場合は Panel) から継承する独自のクラスを作成し、その OnPaint イベントをオーバーライドして、そこに必要なものを描画することです。

まず、そのようなクラスを用意します。

public class BlockBackgroundPanel : Panel
{
    protected override void OnPaint(PaintEventArgs e)
    {
        Graphics g = e.Graphics;
        Image Block = Image.FromFile(@"C:\Users\Administrator\Desktop\movment V1\movment V1\images\BrownBlock.png");
        float recWidth = Block.Width; 
        //rest of your code, replace "genPan" with "this" as you are inside the Panel
    }
}

次に、.Designer.csファイル (Studio で開くことができます) でコードを変更してgenPan、新しいクラス インスタンスになるようにします。

private BlockBackgroundPanel genPan;
//...
this.genPan = new BlockBackgroundPanel ();
于 2013-01-17T11:30:57.427 に答える