none
コントロールのサイズ変更などを検知するには? @ C++/CLI RRS feed

  • 質問

  • お世話になります。

    System::Windows::Forms::UserControl を継承して、Bitmap を内包した、独自のコントロールクラスを作っています。

    Bitmap のサイズは、常にコントロールのサイズと一致させたいので、Size, Width, Height プロパティなどの変更に応じて リサイズするメソッド を呼び出したいのですが、どう実装すればよいのでしょうか?

    理想的には、仮想メソッドとして SetSize(), SetWidth(), SetHeight() のようなセッターがあればオーバーライドできたのですが、生憎ないようですし、どれも 仮想プロパティ でなかったので、プロパティ自体のオーバーライドもできません。

    そこで、リサイズ系のイベントを発生させる以下の2つのメソッドをオーバーライドしてみたのですが、どちらも挙動に不備がありました。

    OnResize
    OnSizeChanged

    コントロールがリサイズされるタイミングは、以下の3ヵ所だと思うのですが、何故か両者とも 2 に反応しません。

    1. 生成される時 @ InitializeComponent()
    this->Custom1 = (gcnew Custom::CustomControl());
    ※ コントロール設計時のデフォルトで Sizeプロパティ が初期化される

    2. レイアウトされる時 @ InitializeComponent()
    this->Custom1->Size = System::Drawing::Size(400, 300);
    ※ レイアウトデザインに応じて Sizeプロパティ が初期化される

    3. ユーザーによる操作 @ 実行時

    つまり、実行時には一見、コントロールがデザイン通りにレイアウトされているものの、内部の Bitmap は、1 のデフォルトサイズのまま、更新されていないという症状が発生しました。

    他に何か、全てのリサイズイベントを確実に検知できるメソッドはあるのでしょうか? もちろん、他のプロパティを含めて、全更新をグローバルに検知できるようなメソッドでも構いません。

    それとも、オーバーライドではない他の正攻法があるのでしょうか?

    何分まだ経験が浅いのですが、何卒ご教授下さい。

    Visual Studio 2008 .NET3.5 @ Windows7 x64

    2011年9月12日 6:19

回答

  • 分かりやすいかと思いまして、OnResize 内から MessageBox で Width と Height の値を表示させてみました。すると起動時、デフォルトサイズが一旦表示されるものの、次に デザインサイズ が表示されると思いきや、その後は何事もなく起動完了してしまうのです。

    MessageBox::Show で Width/Height を ToString したものを表示させてみましたが、デザイン時に配置していたサイズが普通に表示されました。何か特殊なことしていませんか?
    試しに新規でユーザーコントロールを作って、試してみてもらえれば一般事例でないことがおかわりいただけるかと思っています。

    UserControl のコンストラクタで Width/Height を変えてみたり、Size を変えてみたりしましたが、コンストラクタと InitializeComponent の両方のタイミングで呼び出されました。

    C++/CLI 特有の仕様としても、皆さんどう対処されているのか気になります。(^_^;)

    先の投稿の後に試しましたが、C++/CLI でも同じ動きです。
    この辺の挙動は言語依存するようなものではありませんのでご注意ください。


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    2011年9月12日 15:07
    モデレータ

すべての返信

  • コントロールがリサイズされるタイミングは、以下の3ヵ所だと思うのですが、何故か両者とも 2 に反応しません。

    .NET 3.5.1(Win7 x64) で C# のテストコードでは InitializeComponent メソッドの中で Size プロパティに代入する時に OnResize メソッドが呼び出されていました。

    反応しないと言うことはどうやって確かめられたのでしょうか?(ブレークポイント?実行結果?)
    また、サイズを 400x300 から違うサイズに変えても同様にうまく動かないのでしょうか?(その 400x300 が実はデフォルトで変化していないので OnResize が呼び出されない可能性)


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    2011年9月12日 13:52
    モデレータ
  • お返事ありがとうございます。
    反応しないと言うことはどうやって確かめられたのでしょうか?

    分かりやすいかと思いまして、OnResize 内から MessageBox で Width と Height の値を表示させてみました。すると起動時、デフォルトサイズが一旦表示されるものの、次に デザインサイズ が表示されると思いきや、その後は何事もなく起動完了してしまうのです。

    サイズを 400x300 から違うサイズに変えても同様にうまく動かないのでしょうか?

    はい、同コントロールを、デフォルトサイズとは異なる様々なサイズで4枚張っているのですが、デフォルトサイズ が4回メッセージで表示されるだけなのです。

    C++/CLI 特有の仕様としても、皆さんどう対処されているのか気になります。(^_^;)

    • 編集済み luxidea 2011年9月12日 14:40
    2011年9月12日 14:39
  • 分かりやすいかと思いまして、OnResize 内から MessageBox で Width と Height の値を表示させてみました。すると起動時、デフォルトサイズが一旦表示されるものの、次に デザインサイズ が表示されると思いきや、その後は何事もなく起動完了してしまうのです。

    MessageBox::Show で Width/Height を ToString したものを表示させてみましたが、デザイン時に配置していたサイズが普通に表示されました。何か特殊なことしていませんか?
    試しに新規でユーザーコントロールを作って、試してみてもらえれば一般事例でないことがおかわりいただけるかと思っています。

    UserControl のコンストラクタで Width/Height を変えてみたり、Size を変えてみたりしましたが、コンストラクタと InitializeComponent の両方のタイミングで呼び出されました。

    C++/CLI 特有の仕様としても、皆さんどう対処されているのか気になります。(^_^;)

    先の投稿の後に試しましたが、C++/CLI でも同じ動きです。
    この辺の挙動は言語依存するようなものではありませんのでご注意ください。


    質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。
    2011年9月12日 15:07
    モデレータ
  • なるほど、他の要因が本来の動作を阻害している可能性が濃厚だということですね。

    ありがとうございます。オーバーライドが正攻法であることを確認できただけでも安心しました。

    早速、新規にコントロールを作ってみて挙動を比較してみます。

    お忙しいところ、お世話になりました。

    2011年9月12日 16:17