質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.58%

C# PictureBox子要素のOnPaintBackgroundについて

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 2,124

Ineda

score 34

C# PictureBox子要素のOnPaintBackgroundについて

現在C#でドロー系ソフトを作成しています。
開発環境:Win10 visualsturio2012 WindowsForm .net3.5 です。

アプリの概要はピクチャボックス内に、図形要素やテキスト要素をもつコントロールを配置していく感じです。追加するコントロール自体はPictureBoxを継承しています。

![アプリ概要](4d1a3d91d620003cecbd8a0928c6dcd4.png)

現在問題になっているのが、多角形などの要素には透明な背景部分の処理の必要があるため、
以下のサイトを参考にして、OnPaintBackGroundをオーバーライドした関数を使用しています。
http://mitsu.three-atmarks.com/archives/10696

イメージ説明

問題としていること

「ピクチャボックスをクリックする」と
追加したコントロール要素すべてで「OnPaintBackground」が呼び出されてしてしまうことです。
実際には200~300程の点数を追加するため、一度のクリックしただけでかなりの数のビットマップを作成することになり、処理が非常に重くなっています。

試したこと

1.クリック時にフラグ立てる。OnPaintBackgroundをオーバーライドして、何もしない

    

        protected override void OnPaintBackground(PaintEventArgs pevent)
        {
           // ??ピクチャボックスクリックなら何もしない
      if(flag)
             return;

            base.OnPaintBackground(pevent);

            // 以下背面を描画する処理が続く...
         }


自分の中ではこれで解決したと思っていたのですが...(泣)

少なくともこの関数が呼び出された以上はbase.OnPaintBackground(pevent)を呼び出さないと、描画が正しくできません。

しかし、baseの方を呼び出してしまうと、結局背後のコントロールを描画する処理が必要になって処理が重くなってしまいます。

もう、どうしたらいいのか..._| ̄|○

聞きたいこと

わたしは仕事で殆どc言語しか使ったことがないので、ドローソフトのようなイベントを多用するアプリをつくるのは初めてです。

クリックされても、OnPaintBackgroundを呼び出さないとか、そのような処理はできるのでしょうか...?

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+3

直接の回答ではありませんが。。。

子要素もコントロールで作ってるんですよね?
とすると、古典的な Windows OS GUI の仕組みには割と低いところに限界があって、たぶんそれにぶつかっています。

ドローアプリの描画オブジェクトを、Windows.Forms のコントロール(=実体は Windows OS の古典的な GUI オブジェクト)で実装するのは現実的な選択ではないです。

たとえば、Excel の「セル」はコントロールではなく、編集対象となった「セル」の位置に動的にエディットコントロールを張り付けるなどの実装上の工夫がされています。

WPF を使った方がこの手のアプリケーションは作りやすいと思います。

また、Windows.Forms は高解像度環境への対応が非常に弱いので、今後を考えるとあまりお勧めのテクノロジーではありません。

どうしても Windows.Forms で作るとしても、描画オブジェクトをコントロールで実装するのはあきらめて「オフスクリーン」などの適当な技術を学んで実装した方がよいと思います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/05/20 16:07

    回答ありがとうございます。
    WPFは昔触ったのですが、難しくて挫折した記憶があります(笑)
    でも、せっかくなので、今回少しトライしてみます!!

    キャンセル

check解決した方法

0

表示更新処理に一部Invalidateを用いていたことが原因でした。
この関数を呼ぶと、自分自身だけでなく、
自分の子要素のコントロール全てで再描画処理が走るようです。

あとImageプロパティを変更すると、内部的にはInvalidateと同様の処理が実行されるようです。
↓参考サイト
https://dobon.net/vb/dotnet/control/refreshupdateinvalidate.html

各当部分を修正するとそれなりに動くようになりました。
ありがとうございました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.58%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る