DOBON.NETプログラミング道掲示板

[ 最新記事及び返信フォームをトピックトップへ ]

■34892 / inTopicNo.1)  ユーザーコントロールをフォームで使用した時のエラー
  
□投稿者/ たこ 一般人(1回)-(2021/08/24(Tue) 08:45:15)
  • アイコン環境/言語:[VB.NET、.NET Framework 4.7.2] 
    分類:[.NET] 

    いつもお世話になります。いつも参考にさせて頂いており、お世話になっています。

    ユーザーコントロールを作成し、いざFormに張り付けて使用しようとするとエラーが出てしまいます。
    解決方法が判らず、ヒントだけでも頂ければと思い、投稿しました。



    <現状>
    ・ユーザーコントロールテストコンテナーで、単体では正常に動作する。
    ・フォームに張り付け、実行すると「System.ArgumentOutOfRengeException」が発生し、以後Form1[デザイン]を表示しようとしても以下のエラーが表示され、フォームのデザイン画面が表示されない。
    ・エラーが出る場所は判っているが、VisualStudioで自動生成されるコードの為、削除してもまた自動生成されてエラーが出る。



    <エラー内容>
    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    このエラーのインスタンス (2)

    1。 コール スタックの非表示

    場所 System.ComponentModel.ReflectPropertyDescriptor.SetValue(Object component, Object value)
    場所 Microsoft.VisualStudio.Shell.Design.VsTargetFrameworkPropertyDescriptor.SetValue(Object component, Object value)
    場所 System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializePropertyAssignStatement(IDesignerSerializationManager manager, CodeAssignStatement statement, CodePropertyReferenceExpression propertyReferenceEx, Boolean reportError)
    場所 System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeAssignStatement(IDesignerSerializationManager manager, CodeAssignStatement statement)
    場所 System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeStatement(IDesignerSerializationManager manager, CodeStatement statement)

    2。 コール スタックの非表示

    場所 System.ComponentModel.ReflectPropertyDescriptor.SetValue(Object component, Object value)
    場所 Microsoft.VisualStudio.Shell.Design.VsTargetFrameworkPropertyDescriptor.SetValue(Object component, Object value)
    場所 System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializePropertyAssignStatement(IDesignerSerializationManager manager, CodeAssignStatement statement, CodePropertyReferenceExpression propertyReferenceEx, Boolean reportError)
    場所 System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeAssignStatement(IDesignerSerializationManager manager, CodeAssignStatement statement)
    場所 System.ComponentModel.Design.Serialization.CodeDomSerializerBase.DeserializeStatement(IDesignerSerializationManager manager, CodeStatement statement)
    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------



    <エラーが出るソース>
    Form1.Designer.vb内
    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    '
    'EK_Icon1
    '
    Me.EK_Icon1.IconFileCollection = CType(resources.GetObject("EK_Icon1.IconFileCollection"), System.Collections.Generic.List(Of String))
    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    => 上記1行を削除して実行すると正常に実行されFormが表示されて、Form1[デザイン]も正常に表示される。




    <関連しているユーザーフォームのプロパティ>
    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
      ''' <summary>
      ''' 状態表示に使用する状態ファイル名リスト。
      ''' </summary>
      ''' <returns>各状態のファイル名リスト</returns>
      <Category("設定"), Bindable(False), Description("状態表示のアイコンファイル名リスト。")>
      Public Property IconFileCollection As List(Of String)
        Get
          Return _IconFileCollection
        End Get
        Set(value As List(Of String))
          If value Is Nothing Then Exit Property

          DefaultIconUse = False
          If value.Count > StateCount Then
            Throw New Exception("状態アイコンは" & StateCount & "個です")
            Exit Property
          End If
          _IconFileCollection = value
          For x As Integer = 1 To _IconFileCollection.Count - 1
            _IconCollection(x - 1) = Image.FromFile(_IconFileCollection(x - 1))
          Next
          Status = Status
          PictureBox1.Invalidate()
        End Set
      End Property
    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    => Set(value As List(Of String))直下に「If value Is Nothing Then Exit Property」を入れてみたのですが、変わりませんでした。




    <ユーザーアイコン EK-Icon概要>
    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    ・プライベートフィールド _IconCollectionにイメージリストを持っており、パブリックプロパティ「Statsu」に番号を指定すると指定されたイメージを表示する。
    ・パブリックプロパティ DefaultIconUse As BooleanプロパティにTrueを設定するとデフォルトで設定されているイメージになる。(_IconCollectionにデフォルトアイコンを読み込む)
    ・パブリックプロパティ IconFileCollection As List(Of String)にファイル名を設定すると該当ファイルのイメージを_IconCollectionに読み込む。(上記ソース参照)
    ・DefaultIconUseとIconFileCollectionは排他処理。
    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------





    関連している箇所はこんなところだと思っているのですが…
    以上よろしくお願い致します。

マルチポストを報告
違反を報告
引用返信 削除キー/
■34893 / inTopicNo.2)  【追加情報】コントロールをフォームで使用した時のエラー
□投稿者/ たこ 一般人(3回)-(2021/08/24(Tue) 10:02:57)
  • アイコンIconFileCollection プロパティを丸々コメントアウトすると何も問題なく正常に動作します。

    …が、画像を入れ替えて使用したい場合があると考えてのプロパティですので、
    出来れば残したいと思っています。
違反を報告
引用返信 削除キー/
■34894 / inTopicNo.3)  Re[1]: ユーザーコントロールをフォームで使用した時のエラー
□投稿者/ 魔界の仮面弁士 大御所(1395回)-(2021/08/24(Tue) 10:16:40)
  • アイコンNo34892に返信(たこさんの記事)
    > Me.EK_Icon1.IconFileCollection = CType(resources.GetObject("EK_Icon1.IconFileCollection"), System.Collections.Generic.List(Of String))
    .resx ファイルには EK_Icon1.IconFileCollection のエントリーがある状態ですか?
    名前空間のズレがないかも確認を。

    今回、デザイナコード内に永続化したいのは、List(Of ) 内の個々のアイテムですか?
    それとも、それらのアイテムを保持している List(Of ) のインスタンスそのものですか?
    それによって、デザイン時に指定すべき属性値が異なってきます。
    http://www.comrade.co.jp/component/dotnetroom/kt_vsdn/kt_vs5c.htm


    > If value.Count > StateCount Then
    >  Throw New Exception("状態アイコンは" & StateCount & "個です")
    StateCount は固定値ですか。それとも変動値ですか?

    たとえば StateCount が、読み書き可能なプロパティによって変化する値だとしたら、
     ・IconFileCollection がセットされた後で、StateCount の値が小さくなることはないのか?
     ・デザイナコードで永続化されたときに、StateCount と IconFileCollection の永続化順が
      どちらが先に行われても問題が無いような設計になっているか?
    という点が気にかかります。

    プロパティの設定順を考慮する必要がある場合には、UserControl に対して
    ISupportInitialize インターフェイスを Implements するようにします。
    たとえば NumericUpDown の Minimum / Maximum / Value プロパティなどがこの設計です。


    > パブリックプロパティ「Statsu」に番号を指定すると
    スタツ…? Stat数?


    >   Public Property IconFileCollection As List(Of String)
    ところで、ReadOnly Property にはしないのでしょうか。

    たとえば ListView や ListBox の Items プロパティは ReadOnly ですが、
    その中身はデザイン時に保持できる設計になっていますよね。
     ListBox1.Items.Clear() 'OK
     ListBox1.Items.Add("TEST") 'OK
     ListBox1.Items = Nothing 'NG
     ListBox1.Items = ListBox2.Items 'NG

    この場合、DesignerSerializationVisibility 属性で Content を指定しておけば、
    コレクションそのものではなく、コレクションの中身を永続化することができます。


    また、プロパティに List(Of ) を設定しているということで、後から
     Me.EK_Icon1.IconFileCollection(3) = "New Item"
    のような部分差し替えが許可されるのか否か、という疑問もあります。

    許可しないなら、IReadOnlyList(Of ) などの出力専用型を使う選択肢もありますし、
    許可するのなら、変更通知付きコレクション、たとえば ObservableCollection(Of ) などを使えるかと思います。


    > Set(value As List(Of String))
    >   If value Is Nothing Then Exit Property
    >   DefaultIconUse = False
    >   If value.Count > StateCount Then
    >     Throw New Exception("状態アイコンは" & StateCount & "個です")
    >     Exit Property
    >   End If

    Throw の後の Exit Property って意味がないような。

    素の Exception が使われると、後で対処しにくくなるので、自分なら、
     If value Is Nothing Then
      Throw new ArgumentNullException(NameOf(IconFileCollection))
     ElseIf value.Count > StateCount Then
      Throw New ArgumentOutOfRangeException(NameOf(IconFileCollection), "状態アイコンは" & StateCount & "個以下でなければなりません"))
     End If
    のようにするかな。
違反を報告
引用返信 削除キー/
■34895 / inTopicNo.4)  Re[2]: ユーザーコントロールをフォームで使用した時のエラー
□投稿者/ たこ 一般人(4回)-(2021/08/24(Tue) 11:39:20)
  • アイコンNo34894に返信(魔界の仮面弁士さんの記事)


    早速のご回答ありがとうございます。

    > ■No34892に返信(たこさんの記事)
    >>Me.EK_Icon1.IconFileCollection = CType(resources.GetObject("EK_Icon1.IconFileCollection"), System.Collections.Generic.List(Of String))
    > .resx ファイルには EK_Icon1.IconFileCollection のエントリーがある状態ですか?
    > 名前空間のズレがないかも確認を。


    そう言えばリソースにStringリスト作っていません。そこが問題でしょうか…^^;




    > 今回、デザイナコード内に永続化したいのは、List(Of ) 内の個々のアイテムですか?
    > それとも、それらのアイテムを保持している List(Of ) のインスタンスそのものですか?
    > それによって、デザイン時に指定すべき属性値が異なってきます。
    > http://www.comrade.co.jp/component/dotnetroom/kt_vsdn/kt_vs5c.htm


    パッと見た限りでは意味が解りませんでした^^;
    関連していそうな情報なのでじっくり読んでみます。
    情報ありがとうございます。




    >>If value.Count > StateCount Then
    >> Throw New Exception("状態アイコンは" & StateCount & "個です")
    > StateCount は固定値ですか。それとも変動値ですか?
    >
    > たとえば StateCount が、読み書き可能なプロパティによって変化する値だとしたら、
    >  ・IconFileCollection がセットされた後で、StateCount の値が小さくなることはないのか?
    >  ・デザイナコードで永続化されたときに、StateCount と IconFileCollection の永続化順が
    >   どちらが先に行われても問題が無いような設計になっているか?
    > という点が気にかかります。
    >
    > プロパティの設定順を考慮する必要がある場合には、UserControl に対して
    > ISupportInitialize インターフェイスを Implements するようにします。
    > たとえば NumericUpDown の Minimum / Maximum / Value プロパティなどがこの設計です。


    > StateCount は固定値ですか。それとも変動値ですか?


    固定値です。
      Private Const StateCount = 5 * 2
    5つの状態の画像+マウスエンター時の状態画像5枚です。
    状態を増やす事があるかも知れないと考え、定数定義してあります。

    ISupportInitialize 調べました!
    これはこのメソッドが付いている上から順番に実行されると言う認識で良いのでしょうか^^?




    >>パブリックプロパティ「Statsu」に番号を指定すると
    > スタツ…? Stat数?


    Statusのタイプミスです^^;;;;;;;;;;




    >>  Public Property IconFileCollection As List(Of String)
    > ところで、ReadOnly Property にはしないのでしょうか。
    >
    > たとえば ListView や ListBox の Items プロパティは ReadOnly ですが、
    > その中身はデザイン時に保持できる設計になっていますよね。
    >  ListBox1.Items.Clear() 'OK
    >  ListBox1.Items.Add("TEST") 'OK
    >  ListBox1.Items = Nothing 'NG
    >  ListBox1.Items = ListBox2.Items 'NG
    >
    > この場合、DesignerSerializationVisibility 属性で Content を指定しておけば、
    > コレクションそのものではなく、コレクションの中身を永続化することができます。


    外部からファイル名リストをIconFileCollectionプロパティにセットして、画像を変更したいのです…
    デザイン時はコレクションの中身は「無し」と考えており、別に「DefaultIconUse As Boolean = True」と言うプロパティがあり、
    リソースからデフォルトアイコンをコレクションに読み込みます。
    IconFileCollectionにファイル名リストが入力された場合のみイメージを変更したいです。
    上記ListBoxの使い方と同じ使い方をイメージしていますので、属性についても調べてみたいと思います。




    > また、プロパティに List(Of ) を設定しているということで、後から
    >  Me.EK_Icon1.IconFileCollection(3) = "New Item"
    > のような部分差し替えが許可されるのか否か、という疑問もあります。
    >
    > 許可しないなら、IReadOnlyList(Of ) などの出力専用型を使う選択肢もありますし、
    > 許可するのなら、変更通知付きコレクション、たとえば ObservableCollection(Of ) などを使えるかと思います。


    私には難しい領域です^^;
    日々検索して、こうやったらどうか…と研究はしているのですが、知識が追いつきません^^;

    IReadOnlyList …サンプルコードも無く、意味や使い方が解りませんでした…(;^_^A
    変更出来ないコレクション???
    => https://docs.microsoft.com/ja-jp/dotnet/api/system.collections.generic.ireadonlylist-1?view=net-5.0

    ObservableCollection …こちらは使い勝手が良くなりそうですね。場合によっては検討します。




    >>Set(value As List(Of String))
    >>  If value Is Nothing Then Exit Property
    >>  DefaultIconUse = False
    >>  If value.Count > StateCount Then
    >>    Throw New Exception("状態アイコンは" & StateCount & "個です")
    >>    Exit Property
    >>  End If
    >
    > Throw の後の Exit Property って意味がないような。


    やっぱりそうなのですね(;^_^A
    そうじゃないかなとも思ったのですが、自信が無かったもので^^;




    > 素の Exception が使われると、後で対処しにくくなるので、自分なら、
    >  If value Is Nothing Then
    >   Throw new ArgumentNullException(NameOf(IconFileCollection))
    >  ElseIf value.Count > StateCount Then
    >   Throw New ArgumentOutOfRangeException(NameOf(IconFileCollection), "状態アイコンは" & StateCount & "個以下でなければなりません"))
    >  End If
    > のようにするかな。


    例外処理も苦手でして…
    そう言う使い方も出来るのですね。


    いつもいろいろと勉強させて頂いてます。
    ありがとうございます。
違反を報告
引用返信 削除キー/
■34896 / inTopicNo.5)  Re[3]: ユーザーコントロールをフォームで使用した時のエラー
□投稿者/ 魔界の仮面弁士 大御所(1396回)-(2021/08/24(Tue) 13:40:02)
  • アイコンNo34895に返信(たこさんの記事)
    > そう言えばリソースにStringリスト作っていません。そこが問題でしょうか…^^;
    たとえば、ToolStrip をフォームに貼って右クリックすると、
    [標準項目の挿入]メニューが現れますね。

    この場合、Form1.resx 内に各ボタンのアイコン画像記録されるわけですが、
    まず、このような resx が自動生成されていて、その中身が想定通りで
    あるかどうかという点を確認したものです。

    これは、resources.GetObject 自体が失敗しているのか、それとも、
    その値を受け取る側に問題があるのかの切り分けです。


    >> 今回、デザイナコード内に永続化したいのは、List(Of ) 内の個々のアイテムですか?
    >> それとも、それらのアイテムを保持している List(Of ) のインスタンスそのものですか?
    > パッと見た限りでは意味が解りませんでした^^;

    たとえば、ListBox を貼って、デザイン時に Items プロパティに複数行の文字列を書き込んでみてください。

    その場合、Form1.designer.vb に記述される内容は、
    ListBox1.Items = … ではなく、
    ListBox1.Items.AddRange(…) となるはずです。

    これは、Items プロパティが ReadOnly であり、かつ、そのプロパティに
    <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
    という属性が指定されているためです。


    > Private Const StateCount = 5 * 2
    Private Const StateCount As Integer = 5 * 2
    の方が、より望ましいかと思います。

    もっとも、現行の VB バージョンであれば、
     Option Infer Off
     Option Strict On
    に設定されない限りは、自動的に As Integer として解釈されるのですけれどね。


    > ISupportInitialize 調べました!
    > これはこのメソッドが付いている上から順番に実行されると言う認識で良いのでしょうか^^?
    いいえ。「初期化中かどうか」を定義するものです。

    今回の場合、StateCount が固定値であるとのことなので、ISupportInitialize の実装は
    無くても大丈夫そうですが、一応説明しておくと。

    たとえば NumericUpDown の場合、プロパティの最小値≦現在値≦最大値 の関係を
    維持する必要がありますが、Form1.Designer.vb の時点ではその設定順序を制御できません。

    「If value.Count > StateCount Then」も同様で、StateCount が定数ではなく変数だった場合、
    StateCount が確定する前に value が渡されてくることがあり得るわけです。

    このように、各変数間で依存関係があり、設定順序が問題になるようなケースでは、
    そのコントロールやコンポーネントに対して ISupportInitialize を実装しておくと、
    ・InitializeComponent() の冒頭で ISupportInitialize.BeginInit が呼ばれる
    ・InitializeComponent() の最後に ISupportInitialize.EndInit が呼ばれる
    という形で呼び出されるようになります。

    この機構を用いて、BeginInit が呼ばれてから EndInit までのの間は
    『初期化中』として扱うための仕組みを、フラグ等を用いて自力実装します。

    そして初期化中はプロパティの依存関係チェックを行わないようにしておき、
    「初期化中以外でプロパティの setter が呼ばれたとき」や
    「EndInit が呼ばれたとき」には、通常の範囲チェックを行うようにします。



    > 外部からファイル名リストをIconFileCollectionプロパティにセットして、画像を変更したいのです…
    コレクションのインスタンスそのものを受け渡す場合、
     Me.EK_Icon1.IconFileCollection = list1
     Me.EK_Icon2.IconFileCollection = list1
    のような記述も許可されます。この場合、
     Me.EK_Icon1.IconFileCollection(0) = "zero.jpg"
    と書き換えた場合、 EK_Icon2 側の内容も同時に書き換わります。

    また、setter にて .Count をチェックしてはいますが、実際には
     Me.EK_Icon1.IconFileCollection.Add(f)
    のように、後から件数を増減することもできてしまいます。

    これらの操作では、プロパティの setter を通過することなく内容が書き換わるため、
     「If value.Count > StateCount Then」
    のチェックをすり抜けることになりますが、問題ないのでしょうか?
    (たとえば ListBox の場合、Items プロパティと DataSource プロパティは区別していますよね)


    > デザイン時はコレクションの中身は「無し」と考えており、別に「DefaultIconUse As Boolean = True」と言うプロパティがあり、
    > リソースからデフォルトアイコンをコレクションに読み込みます。
    その場合、デフォルトアイコンを必要とする場合は、
    IconFileCollection を永続化しない方が都合が良いかも知れませんね。

    プロパティ値の保存を行うかどうかを制御したい場合には、
     Private Function ShouldSerializeIconFileCollection() As Boolean
      Return Not DefaultIconUse
     End Function
     Private Sub ResetIconFileCollection()
      '_IconCollection と _IconFileCollection のリセット処理
     End Sub
    というメソッドを用意しておけば OK です。詳細は下記参照。
    https://docs.microsoft.com/ja-jp/dotnet/desktop/winforms/controls/defining-default-values-with-the-shouldserialize-and-reset-methods?WT.mc_id=DT-MVP-8907&view=netframeworkdesktop-4.8


    > IReadOnlyList …サンプルコードも無く、意味や使い方が解りませんでした…(;^_^A
    文字通り、読み取り専用版のリストですね。

    読み取り専用版のコレクションを生成するのは簡単です。
     x = Array.AsReadOnly(一次元配列) '「配列」の場合
     x = リスト.AsReadOnly() '「リスト」の場合
    これで、System.Collections.ObjectModel.ReadOnlyCollection のインスタンスが生成されます。

    あるいは AsReadOnly を呼び出す代わりに、下記のようにすることもできます。
     x = New ReadOnlyCollection(Of 型)( リスト )


    >> Throw の後の Exit Property って意味がないような。
    > そうじゃないかなとも思ったのですが、自信が無かったもので^^;
    Throw の直後の行が実行されることがあるとすれば、
    「On Error Resume Next」を併用していた場合ぐらいですね。
違反を報告
引用返信 削除キー/
■34897 / inTopicNo.6)  Re[4]: ユーザーコントロールをフォームで使用した時のエラー
□投稿者/ たこ 一般人(5回)-(2021/08/24(Tue) 17:29:16)
  • アイコンNo34896に返信(魔界の仮面弁士さんの記事)

    回答ありがとうございます。


    > ■No34895に返信(たこさんの記事)
    >>そう言えばリソースにStringリスト作っていません。そこが問題でしょうか…^^;
    > たとえば、ToolStrip をフォームに貼って右クリックすると、
    > [標準項目の挿入]メニューが現れますね。

    〜(略)〜

    > これは、resources.GetObject 自体が失敗しているのか、それとも、
    > その値を受け取る側に問題があるのかの切り分けです。


    私の雑な頭では理解が出来ませんでした^^;




    > >> 今回、デザイナコード内に永続化したいのは、List(Of ) 内の個々のアイテムですか?
    > >> それとも、それらのアイテムを保持している List(Of ) のインスタンスそのものですか?
    >>パッと見た限りでは意味が解りませんでした^^;
    >
    > たとえば、ListBox を貼って、デザイン時に Items プロパティに複数行の文字列を書き込んでみてください。

    〜(略)〜


    > これは、Items プロパティが ReadOnly であり、かつ、そのプロパティに
    > <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
    > という属性が指定されているためです。


    ちょっとListBoxについて調べてみました。
    ItemsプロパティはListBox.ObjectCollectionの参照なのですね…
    で、その参照がReadOnlyになっていると…
    最近ReadOnlyが値だけではなく、参照にも使用出来ると言う事を覚えたばかりです(笑)
    まだまだ勉強が足りません…苦笑


    たった今疑問が生じました。。。
    Public Property IconFileCollection As List(Of String)

    Public ReadOnly Property IconFileCollection As List(Of String)
    …としたとして、別のIconFileCollectionにコレクションを入力するプロパティを作ったとして、
    またそのプロパティに同じエラーが発生しないものでしょうか…
    あ、メソッドで作ってしまえば良いんでしょうかね…
    デザイン時のプロパティで設定出来るのが望ましいですが、
    私の知識が追いつかない為、最悪はメソッドで作ってメソッドでファイル名リストコレクションを渡す事にします。。。



    >>Private Const StateCount = 5 * 2
    > Private Const StateCount As Integer = 5 * 2
    > の方が、より望ましいかと思います。

    〜(略)〜


    たまに型宣言、書き忘れます^^;;;
    ご指摘ありがとうございます。




    >>ISupportInitialize 調べました!
    >>これはこのメソッドが付いている上から順番に実行されると言う認識で良いのでしょうか^^?
    > いいえ。「初期化中かどうか」を定義するものです。

    〜(略)〜

    > この機構を用いて、BeginInit が呼ばれてから EndInit までのの間は
    > 『初期化中』として扱うための仕組みを、フラグ等を用いて自力実装します。


    自力実装するならわざわざIsupportInitializeを使用しなくても良い様な…^^:
    …と思ってしまったダメな子です><




    >>外部からファイル名リストをIconFileCollectionプロパティにセットして、画像を変更したいのです…
    > コレクションのインスタンスそのものを受け渡す場合、
    >  Me.EK_Icon1.IconFileCollection = list1
    >  Me.EK_Icon2.IconFileCollection = list1
    > のような記述も許可されます。この場合、
    >  Me.EK_Icon1.IconFileCollection(0) = "zero.jpg"
    > と書き換えた場合、 EK_Icon2 側の内容も同時に書き換わります。


    そこは思わぬ副産物(笑)
    それはその方が良いです(笑)




    > また、setter にて .Count をチェックしてはいますが、実際には
    >  Me.EK_Icon1.IconFileCollection.Add(f)
    > のように、後から件数を増減することもできてしまいます。
    >
    > これらの操作では、プロパティの setter を通過することなく内容が書き換わるため、
    >  「If value.Count > StateCount Then」
    > のチェックをすり抜けることになりますが、問題ないのでしょうか?
    > (たとえば ListBox の場合、Items プロパティと DataSource プロパティは区別していますよね)


    問題大ありです(笑)
    一応ほとんどはプライベートフィールドになっており、直接は書き換えられない様にはなっています。

      Private _IconFileCollection As New List(Of String)




    >>デザイン時はコレクションの中身は「無し」と考えており、別に「DefaultIconUse As Boolean = True」と言うプロパティがあり、
    >>リソースからデフォルトアイコンをコレクションに読み込みます。
    > その場合、デフォルトアイコンを必要とする場合は、
    > IconFileCollection を永続化しない方が都合が良いかも知れませんね。


    そこは考えました!

      Private _DefalutIconUse As Boolean = True

    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
      ''' <summary>
      ''' デフォルトのアイコンを使用する時にTrueにします。
      ''' </summary>
      ''' <returns></returns>
      <Category("設定"), Bindable(True), Description("デフォルトのアイコンを使用する時にTrueにします。")>
      Public Property DefaultIconUse As Boolean
        Get
          Return _DefalutIconUse
        End Get
        Set(value As Boolean)
          DefalutIconUse = value
          If _DefalutIconUse Then
            Dim asm As System.Reflection.Assembly = System.Reflection.Assembly.GetExecutingAssembly()
            Dim rm As New System.Resources.ResourceManager(asm.GetName().Name + ".Resources", asm)
            Dim bmp As Bitmap = Nothing

            _IconFileCollection.Clear()
            For x As Integer = 1 To StateCount
              bmp = CType(rm.GetObject(x), Bitmap)
              Me._IconCollection.Add(bmp)
            Next
          Else
            _IconCollection.Clear()
            PictureBox1.Image = Nothing
          End If
        End Set
      End Property
    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------




    > プロパティ値の保存を行うかどうかを制御したい場合には、
    >  Private Function ShouldSerializeIconFileCollection() As Boolean
    >   Return Not DefaultIconUse
    >  End Function
    >  Private Sub ResetIconFileCollection()
    >   '_IconCollection と _IconFileCollection のリセット処理
    >  End Sub
    > というメソッドを用意しておけば OK です。詳細は下記参照。
    > https://docs.microsoft.com/ja-jp/dotnet/desktop/winforms/controls/defining-default-values-with-the-shouldserialize-and-reset-methods?WT.mc_id=DT-MVP-8907&view=netframeworkdesktop-4.8


    これは…
    リセット出来るプロパティを作る…と言う認識でよろしいのでしょうか^^?
    上記ホームページ内、下の方の「関連項目」の少し上…
    ------------------------------------------------------------------------------------------------------
    代わりに、ShouldSerialize および Reset メソッドを MyFont プロパティに対して実装する必要があります。
    ------------------------------------------------------------------------------------------------------
    …と書かれていますが、プロパティにメソッドを作成する事が出来るのですか?




    >>IReadOnlyList …サンプルコードも無く、意味や使い方が解りませんでした…(;^_^A
    > 文字通り、読み取り専用版のリストですね。
    >
    > 読み取り専用版のコレクションを生成するのは簡単です。


    これはどうやって初期化するのかなと思ってしまいました。
    ReadOnly Propertyと同じ様にコンストラクタだけで初期化出来るのでしょうか?




    > >> Throw の後の Exit Property って意味がないような。
    >>そうじゃないかなとも思ったのですが、自信が無かったもので^^;
    > Throw の直後の行が実行されることがあるとすれば、
    > 「On Error Resume Next」を併用していた場合ぐらいですね。


    ご教授ありがとうございます。
    …と言うか…
    On Error Resume Nextと併用が出来るのですね…

    まだまだ初心者の域を脱しません…^^;
違反を報告
引用返信 削除キー/
■34898 / inTopicNo.7)  Re[5]: ユーザーコントロールをフォームで使用した時のエラー
□投稿者/ たこ 一般人(6回)-(2021/08/26(Thu) 21:58:39)
  • アイコンNo34897に返信(たこさんの記事)


    いろいろとご指導頂きありがとうございました。

    とりあえず今回は、
      Public Property IconFileCollection As List(Of String)



      Public WriteOnly Property IconFileCollection As List(Of String)
    と、WriteOnlyにする事でエラーが出なくなりましたので、
    今回はこれで行きたいと思います。
    本当ならばデザイン時にも設定をしたいところではありますが、
    勉強が追いつきません…

    また進展があればご報告致します。
    ありがとうございました。
解決み!
違反を報告
引用返信 削除キー/



トピック内ページ移動 / << 0 >>

このトピックに書きこむ

Mode/  Pass/


- Child Tree -