none
自作コンポーネントのプロパティ(PointF構造体)がデザイナーのジェネレータで正しく変換されない RRS feed

  • 質問

  • 誤ってC#のフォーラムへお問い合わせしてしまった「自作コンポーネントのプロパティ(PointF構造体)がプロパティウィンドウ上で編集できない」件の続きです。

    C++(CLR)にて作成しているコンポーネントでPointF構造体を用いたプロパティがプロファイルウィンドウ上で編集できないという件については、前回回答をいただいた方法 『ExpandableObjectConverterを継承したクラスを作成し、String/PointFの変換メソッドを追加する』 ことで解決できたのですが、デザイナーのジェネレータがPointF構造体を正しく変換できないという部分は解決できませんでした。

    ≪ジェネレータの変換結果: 問題点は強調部分です。≫

    ● 正: 以下のように変換されることを期待するのですが、

       //
       // XXXXControl1
       //
       this->XXXXControl1->Origin = System::Drawing::PointF(0, 0);
       this->XXXXControl1->Scale = System::Drawing::SizeF(0, 0);

    ● 誤: 以下のように変換されてしまいます。

       //
       // XXXXControl1
       //
       this->XXXXControl1->Origin = (*cli::safe_cast<System::Drawing::PointF^>(resources->GetObject(L"XXXXControl1.Origin")));
       this->XXXXControl1->Scale = System::Drawing::SizeF(0, 0);

    ● この結果、実行モジュールは作成できますが、起動時に以下のようなアラームが発生します。

    'System.Resources.MissingManifestResourceException' のハンドルされていない例外が mscorlib.dll で発生しました。

    追加情報: 指定されたカルチャまたはニュートラル カルチャに対して適切なリソースが見つかりませんでした。"SLCControlLibrary.CSampleAppl.resources" が適切に埋め込まれたか、実行時にアセンブリ "SLCControlLibrary" にリンクされたか、または必要なサテライト アセンブリが読み込まれて完全に署名されていることを確認してください。

    デザイナーのジェネレータコード生成部分について、何かご存じの方がおられましたら教えていただけないでしょうか。

    よろしくお願いいたします。

    2010年8月18日 1:17

すべての返信

  • 普通はそれでも問題ないはずですけどね。まあ C++/CLI のデザイナは個人的には信用度低いので、ちょっと複雑なことするとすぐにそう言うことになっても不思議ではないと思ってしまいますけど。

    XXXXControl と、それをメンバに持っている this は、それぞれ別のプロジェクトに存在しているものでしょうか? また this は Form ですか? どのプロジェクトが実行ファイルとなりますか?

    ソリューションエクスプローラで this のクラスの .h の下位ツリーに 同名の resx ファイルが存在していると思いますが、それを開くと System.Drawing.PointF 型の XXXXControl1.Origin という名前をしたリソースは存在していますか?

     

    以下は自動生成についてです。

    InitializeComponent 内で自動生成されるコードについては、まず以下のページをご覧下さい。

    株式会社コムラッド/コントロールの設定値を永続化する

    TypeConverter などを実装しない Serializable なオブジェクトは、設定がシリアライズされてリソースに格納され、初期化時にそのリソースを取得してデシリアライズし変数に格納し直すようになっています。

    これは上記リンクのパターン 5 の挙動で、お望みの挙動はパターン 2 の方でしょう。リンク先にはこの挙動を使えるようにするサンプルものっていますが、残念ながら既存の型についてはこれを実装することはできません。

    Different TypeConverter settings on type and property has inconsistent behavior | Microsoft Connect

    ここにあるように、CanConvertTo/ConvertTo で InstanceDescriptor を使うのは class に対して設定された TypeConverter のみであり、プロパティに対して設定された TypeConverter は InstanceDescriptor への変換問い合わせが発生しないのです。

    既存の型に後から TypeConverter を設定するのは(デザイナであれこれするタイミングでは)多分不可能なので、InstanceDescriptor を使うのも不可能ということになります。

    CodeDomSerializer 派生クラスを作って Serialize を書き直しって方法でいけるかもしれませんが。System::Drawing::PointF と変換可能な独自の value class PointF を作った方が早いかも。

    • 回答の候補に設定 山本春海 2010年9月3日 2:50
    2010年8月18日 7:03
  • Hongliang様

    いつも対応していただき、ありがとうございます。 以下、お尋ね頂いた項目に関してお返事いたします。

    ● XXXXControl と、それをメンバに持っている this は、それぞれ別のプロジェクトに存在しているものでしょうか? また this は Form ですか? どのプロジェクトが実行ファイルとなりますか?

    XXXXControlは、System::Windows::Forms::UserControlを継承して作成したコントロールです。このコントロールをツールボックスに登録しています。 この登録したコントロールをSystem::Windows::Forms::Formを継承して作成されたアプリケーション上に配置します。 this->XXXXControl1のオブジェクトはこの時作成されたものです。

    ● ソリューションエクスプローラで this のクラスの .h の下位ツリーに 同名の resx ファイルが存在していると思いますが、それを開くと System.Drawing.PointF 型の XXXXControl1.Origin という名前をしたリソースは存在していますか?

     <data name="XXXXControl1.Origin" mimetype="application/x-microsoft.net.object.binary.base64">
        <value>
            AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0yLjAuMC4wLCBDdWx0
            dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJh
            d2luZy5Qb2ludEYCAAAAAXgBeQAACwsCAAAAAAAAAAAAAAAL
    </value>
      </data>

    このコードのことですよね。 PointF以外のプロパティはありませんが、PointFのプロパティは存在しています。

     

    ご紹介頂いた資料や回答頂いた内容について、まだ消化できておりません。 じっくり読み返して対応方法を考えたいと思います。

    まずは、お礼まで。

    2010年8月18日 9:39
  • おすすめ頂いた通りMyPointFクラスを作成いたしました。 作成したクラスにてプロパティウィンドウ上での編集までできるようになりましたが、今度は「PublicKeyToken=null が見つかりません。]というエラーが発生します。 どうも「簡易名」,「バージョン番号」,「サポートされているカルチャ」は取得できていますが、「暗号化キーペア(公開キー トークン)」が取得できないようです。

    設定値は、「アプリケーションまたはアセンブリに署名するときに使用した公開キーの SHA-1 ハッシュの最後の 8 バイトを設定する」となっていますが、その取得方法や設定方法に関する資料が見つけられませんでした。

    何か参考になる資料をご存知でしたら紹介していただけないでしょうか。 よろしくお願いいたします。

    2010年8月19日 3:37