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

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

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

イベントハンドラ

マウスのクリックなどの特定の事象(イベント)が発生した時に実行される処理のことをイベントハンドラと呼びます。

ドラッグ&ドロップ

コンピューターのGUIにおいて、バーチャルなものを「つかむ」ことによって選択し、別の場所や他のバーチャルなものの上に動かす行為、またはその行為に対応していることを指す。

Q&A

解決済

2回答

3963閲覧

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

Ineda

総合スコア45

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

イベントハンドラ

マウスのクリックなどの特定の事象(イベント)が発生した時に実行される処理のことをイベントハンドラと呼びます。

ドラッグ&ドロップ

コンピューターのGUIにおいて、バーチャルなものを「つかむ」ことによって選択し、別の場所や他のバーチャルなものの上に動かす行為、またはその行為に対応していることを指す。

0グッド

0クリップ

投稿2017/05/20 06:38

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

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

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

アプリ概要

現在問題になっているのが、多角形などの要素には透明な背景部分の処理の必要があるため、
以下のサイトを参考にして、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を呼び出さないとか、そのような処理はできるのでしょうか...?

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

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

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

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

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

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

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

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

投稿2017/05/20 06:47

編集2017/05/20 12:58
hidori

総合スコア402

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Ineda

2017/05/20 07:07

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

0

自己解決

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

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

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

投稿2017/06/01 07:16

Ineda

総合スコア45

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問