c#のOnPaintメソッドが呼び出されない原因とは?

このQ&Aのポイント
  • c#初心者がコントロールで描画を行う際、OnPaintメソッドが呼び出されない問題に遭遇しました。
  • 通常はControlクラスのTextプロパティに異なる値を設定するとOnPaintメソッドが呼ばれますが、特定の条件下では呼ばれないことがあります。
  • OnPaintメソッドを必ず呼びたい場合にはRefreshメソッドを利用することもできますが、原因を突き止めたいと考えています。ご意見やアドバイスをお待ちしています。
回答を見る
  • ベストアンサー

c# OnPaintメソッドが呼び出されない原因

 こんにちは、c#初心者です。  コントロールで描画を行う際、そのほとんどをOnPaintメソッドに頼っているのですが、ちょっと問題が発生しました。  通常、ControlクラスのTextプロパティに現在とは異なる値を設定すると結果としてOnPaintメソッドが呼ばれるのですが、ある条件下では呼ばれないこともあるみたいです。  前提条件として、 ・通常はOnPaintメソッドが正常に呼ばれる、 ・Visibleはtrue、 ・画面上に表示されている(画面内かつ上に何も覆われてない)、 ・Textプロパティはオーバーライドされていない、 ・その他、OnTextChangedメソッドとAutoSizeプロパティくらいしかオーバーライドされていない、 ・SuspendLayoutが原因ではないような気がする、 という状態なのですが、呼ばれない場合があるようです。ブレイクポイント+ステップイン/オーバーも疲れて、これ以上してたら死にそうです。  そこで皆様に考えうる原因を列挙して頂きたいのです。  単にOnPaintメソッドを必ず呼びたいのなら、最悪、Refreshメソッドなどを使えばいいのですが、それとこれとは別問題で、知識として蓄えておこうかと。  それと、対処療法的(原因ではなく症状を抑える)な方法をあまりとりたくないのもあります(それだったら、まだ全くの未完成なので、構造ごと変えてもいいのですが)。  どなたか分かる方、いらっしゃいましたら教えていただけませんか?

質問者が選んだベストアンサー

  • ベストアンサー
noname#159825
noname#159825
回答No.2

ANo1 です。 Text プロパティの変更 => WM_PAINT の発生といえば確実に実装されていると思われるテキストボックスかと思いました。ボタンとか?まぁ、この際さほど関係ないんですが・・・。 どちらにせよTextChange ハンドラでInvalidate を呼ぶのが普通な気がします。重複してOnPaint よばれないし。

koumei000
質問者

お礼

 結局、対処療法的処置になりましたが、今回はこれで妥協します。回答ありがとうございました。

その他の回答 (1)

noname#159825
noname#159825
回答No.1

onpaint が呼ばれない時。textbox が画面に表示されてない時とか?つまり別のウィンドウの背後に隠れているときとか。 まぁRefresh ではなくInvalidate を使いますよね。OnPaint が呼ばれるタイミングはWindows の描画タイミングに由来するので。 まぁテキストボックスのようなコントロールのオーナードローは、別にプロパティを設定しないといけないとか、そんなのもあった気がします。

koumei000
質問者

お礼

 回答ありがとうございます。 > textbox が画面に表示されてない時とか? > つまり別のウィンドウの背後に隠れているときとか。 ・画面上に表示されている(画面内かつ上に何も覆われてない)、の前提条件があります。 > まぁRefresh ではなくInvalidate を使いますよね。  そういえば、そんなのもありました。  それと、テキストボックスの単語が目立つのですが、テキストボックスとは言っていませんよ? 分かってらっしゃるなら問題ありませんが(ちなみに大半はControlからの継承です)。

関連するQ&A

  • なぜprotected overrideなのか

    C#でわからないことが2,3あるのですが、このmsndのサンプルで public class FirstControl : Control{ public FirstControl() {} protected override void OnPaint(PaintEventArgs e) { // Call the OnPaint method of the base class. base.OnPaint(e); // Call methods of the System.Drawing.Graphics object. e.Graphics.DrawString(Text, Font, new SolidBrush(ForeColor), ClientRectangle); } } これのprotected override void OnPaint(PaintEventArgs e){} の部分なのですが、なぜprotected overrinde修飾子なのでしょう 何をオーバーライドしてるのですか?他のサンプルにも構文のように出てくるのですが。 あとOnPaintはメソッドのようですがイベントを発生させるにはデリゲートではないのでしょうか あとPaintEventArgsはクラスということですがnewはいらないのでしょうか。staticがどこかにあるのでしょうか よろしくお願いします。

  • VB6のユーザーコントロールの受け渡しでプロパティ

    自作のユーザーコントロールをフォームに貼り付け、 それをクラスに渡してクラス内でそのコントロールのVisibleを制御しようとしておりますが、 フォームからコントロールのVisibleプロパティにアクセスできますが、 クラスからだと、 メソッドまたはデータメンバが見つかりません とコンパイルエラーが出ます。 そこで、コントロールをControlやUserControlにキャストしてみましたが 型が一致しません というエラーとなってしまいます。 コントロールにVisibleプロパティの追加を試みましたが、 ActiveXコントロールインタフェースウィザードの使用できる名前に於いて それらのプロパティが列挙されません。 対象がユーザーコントロールでなく、ボタンなどの標準コントロールの場合は できたのですが・・・ なにか方法をご存知でしたらご教授ください。

  • ActiveXコントロールにオブジェクトの追加?

    VB6SP6です。 ActiveXコントロールにはプロパティ・メソッド・イベントが設定できることがわかりました。 オブジェクトの追加ってできますか? 使用する側から 通常は「ActiveX名.メソッド」とするところを 「ActiveX名.オブジェクト名.メソッド」というようにメソッドを呼び出したいのです。 へんちくりんな質問でしたらすみません。 どなたかわかる方いらっしゃいましたらよろしくお願いいたします!

  • OnPaintメソッドが実行されずに、困っています

    JScript .NET に関する質問なので、カテゴリが違うと思いますが、ご存知の方がいらっしゃったらよろしくお願いします。 import Accessibility; import System.Drawing; import System.Windows.Forms; new Form1().ShowDialog(); class Form1 extends Form { function Form1() { Text = "Form1"; BackColor = SystemColors.Window; ForeColor = SystemColors.WindowText; ResizeRedraw = true; } protected function OnPaint(e) { var g = e.Graphics; var pen = new Pen(ForeColor); g.DrawLine(pen, 0, 0, ClientSize.Width - 1, ClientSize.Height - 1); g.DrawLine(pen, 0, ClientSize.Height - 1, ClientSize.Width - 1, 0); } }

  • 画面プロパティが表示されない。

    コントロールパネルから画面で画面プロパティが表示されない。 画面をクリックしても何も起きない。どういった原因が考えられるでしょうか?

  • C++BuilderにてEFCreateErrorが回避できません

    こんにちは。プログラミング初心者でくだらない質問だったら申し訳ないのですが、調べてもどうしても解決できなかったので質問させて下さい。お手数をおかけしますが宜しくお願い致します。 C++Builderにて単純なプログラムを作成しています。 内容はTEditコンポーネント,TButtonコンポーネント,TOpenDialogコンポーネントを設置し、TButtonのクリックイベントでOpenDialogのExcecuteメソッドを呼びます。 ExcecuteメソッドがtrueだったらOpenDialogのFileNameプロパティの値をTEditのTextにコピーし、そのText、つまりファイルのフルパスをExtractFileName関数でファイル名のみにした値をTStringList型にAddします。 そして最後に保存ボタンクリックでTStringListオブジェクトのSaveToFileメソッドで保存する、という内容なのですが、保存ボタンクリック時にEFCreateErrorが発生してしまいます。 常に発生するのであれば原因も絞れるのですが、「OpenDialogのExcecuteメソッドを呼び出した場合のみ」という条件で例外が発生してしまい、原因が分からず困っております。 つまり、手入力でTEditに入力した場合などは正しく保存できるのですが、OpenDialogにてファイルパスを選択した場合のみ発生してしまいます。 これはどのような原因が考えられますでしょうか?

  • ユーザーコントロールのメソッドにクラスの配列を渡すとエラーが

    意味不明のバグで立ち往生しています。 原因追求のため下の状態までコードを削ったのですが 「MyUserControl1.F clss」の所で 「コンパイルエラー:ByRef引数の型が一致しません。」 というメッセージが出てきてしまいます。 '--------フォームモジュール Form1のコード---------- Private Sub Form_Load() Dim clss(5) As New MyClass MyUserControl1.F clss End Sub '--ユーザーコントロール MyUserControlのコード----- Public Sub F(arg() As MyClass) End Sub '-------クラスモジュール MyClassのコード----------- '(無し) 色々といじってみると 「ユーザーコントロールのメソッド」「クラス」「配列」 の条件が全て揃うと出てくるエラーみたいなんですが 対処方法がさっぱり解りません。 私はメニューからユーザーコントロールを見つけて 使えるのではと考え使ってみたレベルなので どこかで根本的なミスを犯しているのかもしれませんが 何か気づくところがあればよろしくお願いします。

  • フリーズの原因が知りたいです

    http://okwave.jp/qa/q6431865.html 前回の質問です。 フリーズする頻度が高くなってきました。 フリーズの状況 ・突然 ・シャットダウン、休止、スタンバイ 各状態になる直前 ・スタンバイの復帰時 ・ディスククリーンアップを起動して間もなく やってみたこと ・AVG Free、Spybot、Ad-Awere でスキャン ・チェックディスク、デフラグ ・システムの復元 ・怪しいと思った SP3、AVG、Firefox を削除、SP3以外は入れ直し。 いずれも変化はありません。 画面のプロパティの問題 画面の解像度の数が元は5つ。PCを起動して最初に開くと、14もある。1度開いて以降は5つに戻る。再起動するとまた増える。 元からあるもの以外を適用しようとすると、 【コントロール パネルの[画面]は、ディスプレイの設定を変更できません。これらの設定を変更するには、管理者特権が必要です】 【このディスプレイの設定は無効です。違う組み合わせのディスプレイ設定を試してください。】 のアラートが出た後、5つになる。 OS:XP Pro SP2(SP3は削除してみてから入れ直してません。) CPU:Pentium 4 1.80GHz メモリ:640MB フリーズの原因も知りたいですが、画面のプロパティの現象がフリーズと関係があるのかどうかも知りたいです。

  • 他クラスからForm1内コントロルの操作方法を教えて(C#プログラミン

    他クラスからForm1内コントロルの操作方法を教えて(C#プログラミング) Form1で定義してあるtextBox1のText値を他クラスから操作したいのですが、そのコーディング要領が判らず困っております。どなたか教えてくださいませんか? 我流で下記の様なソース(要点のみ記述、他は省略)を作ってみましたが、コンパイルエラー「'object' に 'textBox1' の定義が含まれておらず、型 'object' の最初の引数を受け付ける拡張メソッドが見つかりませんでした。using ディレクティブまたはアセンブリ参照が不足しています。」がでます。 このエラーメッセージの意味を理解できず、何故Form1オブジェクトが伝わらないのか判らず、どこをどう直せばよいのか途方に呉れております。 以下我流C#ソースの抜粋 delegate void SetTextCallback(string text); public class Form1 {   通常のForm内コントロールの定義 Object formobj = this;   AAAclass aaa = new AAAclass (formobj);   この後Aclass内の基幹メソッドを走らせる } public class AAAclass { private Object formObject = null; public AAAclass(Object formobj) { formObject = formobj;    様々な初期化処理 } private void textDisplay(string text) { if (formObject.textBox1.InvokeRequired){  //この行の"textBox1"部分がエラー SetTextCallback d = new SetTextCallback(textDisplay); formObject.Invoke(d, new object[] { text }); //この行の"Invoke"部分がエラー } else { formObject.textBox1.Text = text;  //この行の"textBox1"部分がエラー } } この後、複数のスレッドを定義し、走らせている   それらのスレッドで上記の共通テキスト表示メソッドを利用している }

  • Word2007応用 コンテンツコントロールについて

    WindowsXPからWindows7に買い替えて、Word2007を勉強しています。(テキストを使った方法で。)応用編でコンテンツコントロールの挿入について操作するところをやっています。そこで、コンボボックスコンテンツコントロールを挿入したいのですが、「開発」→「コンボボックス」→「コントロールのプロパティー」を押すとなぜかドロップダウンコンテンツコントロールのプロパティー画面になり、コンボボックスが設定できません。ほかの「日付の選択」や「テキスト」「ドロップダウンリスト」などはそれぞれのプロパティーがちゃんとでます。なぜでしょうか?PCのことは詳しくないので全く原因がわからない状態です。PCに詳しい方、ぜひ教えていただけないでしょうか?よろしくお願いいたします。なお、新しいPCは富士通FG90DWです。

専門家に質問してみよう