11

私は現在、StackOverflow の他の場所で見つけた次の便利なコードを持っています。

form.DrawToBitmap(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));

いくつかのテキスト ボックス/ドロップダウンと大きな画像ボックスを含むフォームがあります。次に、この大きな画像ボックスの上に小さな画像ボックスを配置します。

撮影したスクリーンショットを見ると、フォームは表示されるのですが、大きな画像ボックスの上に配置された小さな画像ボックスが何らかの理由で表示されませんか?

4

2 に答える 2

18

Control.DrawToBitmap()のドキュメントにこの制限があります。

コンテナ内のコントロールは逆の順序でレンダリングされます。

つまり、2つのコントロールが互いにオーバーラップする場合、通常はもう一方の「下」にレンダリングされる(最初に描画され、次にオーバーラップするコントロールによってオーバードローされる)代わりに、最後にレンダリングされます(したがって、通常はオーバーラップするコントロールとオーバーラップします)。あなたの場合、小さなコントロールが大きなコントロールの境界の内側とその上に完全に描画される場合、コントロールはこの逆レンダリングによって非表示になります。

小さいものと重なっている大きいPictureBoxでBringToFront()とSendToBack()を使用して、これを回避してみてください。ビットマップに描画する直前にBringToFront()を呼び出し、完了したらSendToBack()を呼び出します。ユーザーに画面のちらつきを見せたくない場合は、Zオーダーを変更する前にSuspendLayout()を呼び出し、適切なZオーダーにリセットした後にResumeLayout(true)を呼び出してみてください。

于 2012-04-10T20:59:33.550 に答える
1

手伝ってくれてKeithSに感謝!

これらのリバース&リバースバックを行うためのコードが必要な人のために、ここに行きます:

    private void ReverseControlZIndex(Control parentControl)
    {
        var list = new List<Control>();
        foreach (Control i in parentControl.Controls)
        {
            list.Add(i);
        }
        var total = list.Count;
        for (int i = 0; i < total / 2; i++)
        {
            var left = parentControl.Controls.GetChildIndex( list[i]);
            var right = parentControl.Controls.GetChildIndex(list[total - 1 - i]);

            parentControl.Controls.SetChildIndex(list[i], right);
            parentControl.Controls.SetChildIndex(list[total - 1 - i], left);
        }                        
    }

    private void SaveImage()
    {
        SaveFileDialog sf = new SaveFileDialog();
        sf.Filter = "Bitmap Image (.bmp)|*.bmp|Gif Image (.gif)|*.gif|JPEG Image (.jpeg)|*.jpeg|Png Image (.png)|*.png|Tiff Image (.tiff)|*.tiff|Wmf Image (.wmf)|*.wmf";
        if (sf.ShowDialog() == DialogResult.OK)
        {
            int width = pnlCanvas.Size.Width;
            int height = pnlCanvas.Size.Height;

            Bitmap bm = new Bitmap(width, height);


            SuspendLayout();
            // reverse control z-index
            ReverseControlZIndex(pnlCanvas);

            pnlCanvas.DrawToBitmap(bm, new Rectangle(0, 0, width, height));

            // reverse control z-index back
            ReverseControlZIndex(pnlCanvas);
            ResumeLayout(true);

            bm.Save(sf.FileName, ImageFormat.Bmp);
        }

    }
于 2017-11-28T12:31:05.500 に答える