C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Component内で自身のname

[トピック内 7 記事 (1 - 7 表示)]  << 0 >>

■95223 / inTopicNo.1)  Component内で自身のname
  
□投稿者/ 殿下 (1回)-(2020/07/02(Thu) 13:57:23)

分類:[.NET 全般] 

コントロールを配列にするために、拡張プロバイダコンポーネントを作っています。

<ProvideProperty("Index", GetType(Text))>
Public Class TextArray
    Inherits Component
    Implements ISupportInitialize
    Implements IExtenderProvider
    Public Function CanExtend(ByVal target As Object) As Boolean Implements IExtenderProvider.CanExtend
        If TypeOf target Is Text Then
           Return False
        Else
            Return False
        End If
    End Function
End Class

ここで、CanExtend において、
拡張プロバイダコンポーネントを適用するコントロールを
自身のコンポーネントnameをコントロールnameに含んでいるコントロールだけに絞りたいのですが、
Me,MyClassには該当する要素を持っておらず、
自身のnameをどのようにして参照するか不明で困っております。
どの技法を用いれば自身のnameを参照できるようになるのか、
お知恵をお貸し頂きたく、願い致します。

引用返信 編集キー/
■95232 / inTopicNo.2)  Re[1]: Component内で自身のname
□投稿者/ 魔界の仮面弁士 (2767回)-(2020/07/02(Thu) 15:55:13)
No95223 (殿下 さん) に返信
> 拡張プロバイダコンポーネントを作っています。

……?

拡張プロバイダーという割には、IExtenderProvider.CanExtend で
True が返されるパターンが書かれていないように見えます。

Return 部のインデントが微妙にずれているようなので、掲示板投稿時の記述ミスでしょうか。


> ここで、CanExtend において、
> 拡張プロバイダコンポーネントを適用するコントロールを
> 自身のコンポーネントnameをコントロールnameに含んでいるコントロールだけに絞りたいのですが、

ここでいう name とは、「型名」のことでしょうか。
(Me.TextBox1.Name 相当の「コントロール名」ではなく)

型名を得るだけなら、
 strComponentTypeName = NameOf(TextArray)
 strControlTypeName = NameOf(Text)
あるいは
 strTypeName = TypeName(Me)
 strTypeName = GetType().FullName
などと書けなくはないですが、型判定であるのなら、コンパイル時にチェックされるよう、
最初の質問の通り、TypeOf で型判定した方が良いと思います。


<ProvideProperty("Index", GetType(Control))>
Public Class TextArray
 Inherits Component
 Implements ISupportInitialize
 Implements IExtenderProvider

 Public Function CanExtend(target As Object) As Boolean Implements IExtenderProvider.CanExtend
  Return TypeOf target Is Text
 End Function

 'GetIndex / SetIndex / BeginInit / EndInit の実装は割愛
End Class



> コントロールnameに含んでいるコントロールだけに

どうしても名前で指定する必要があるとしても、『含む』という条件にしてしまうと、
"TextureArray" 拡張プロバイダーが
"Text" コントロールを拡張してしまう危険性がありそうです。

ルール付けをもう少し狭めて、たとえば「対象コントロールの型名 + "Array"」のような
条件にした方が良いかもしれません。

ただ、名前空間が異なる同名クラスの扱いも検討する必要がでてきますので、
個人的にはやはり、文字列判定はお奨めしません。まぁ、要件次第ですけれどね。
引用返信 編集キー/
■95235 / inTopicNo.3)  Re[2]: Component内で自身のname
□投稿者/ 殿下 (2回)-(2020/07/02(Thu) 16:28:17)
class名やassemblymbly名ではなく、coltrol名の方で判別したいのです。
TypeOfで先にclassで絞ったあとで、control.nameでさらに絞りたかった為です。

'MyTextArray1の対象にしたいもの
Public WithEvents _MyText1_0 As MyText : _MyText1_0.Name = "_MyText1_0"
Public WithEvents _MyText1_1 As MyText : _MyText1_1.Name = "_MyText1_1"
Public WithEvents MyText1 As MyTextArray : MyTextArray1.Name = "MyText1 "

'MyTextArray2の対象にしたいもの
Public WithEvents _MyText2_0 As MyText : _MyText2_0.Name = "_MyText2_0"
Public WithEvents _MyText2_1 As MyText : _MyText2_1.Name = "_MyText2_1"
Public WithEvents MyText2 As MyTextArray : MyTextArray2.Name = "MyText1"

この様な場合、
MyText1 には、"MyText1"を含む"_MyText1_0"と"_MyText1_1"を
MyText2 には、"MyText2"を含む"_MyText2_0"と"_MyText2_1"を
としたい訳だったのです。

引用返信 編集キー/
■95236 / inTopicNo.4)  Re[3]: Component内で自身のname
□投稿者/ 殿下 (3回)-(2020/07/02(Thu) 16:34:13)
coltrolの方は、nameプロパティを持っているので参照でしくのですが、
ExtenderProviderの方は、nameプロパティを持っていない為、
判定ができない為、ExtenderProviderの方のnameをなんとか参照できないものかと。
という事でした。
引用返信 編集キー/
■95239 / inTopicNo.5)  Re[4]: Component内で自身のname
□投稿者/ 魔界の仮面弁士 (2768回)-(2020/07/02(Thu) 19:42:07)
No95236 (殿下 さん) に返信
> coltrolの方は、nameプロパティを持っているので参照でしくのですが、
> ExtenderProviderの方は、nameプロパティを持っていない為、

System.Windows.Forms.Control クラスには Name プロパティがあるが、
System.ComponentModel.Component クラスには Name プロパティが無い、ということですね。


無ければ追加しましょう。


<ProvideProperty("Index", GetType(Control))>
Public Class TextArray
 Inherits Component
 Implements ISupportInitialize
 Implements IExtenderProvider

 Private _Name As String
 <Browsable(False)>
 Public Property Name As String
  Get
   If Site IsNot Nothing Then
    _Name = Site.Name
   End If
   Return _Name
  End Get
  Set(newName As String)
   If Site IsNot Nothing Then
    Site.Name = newName
   End If
   _Name = newName
  End Set
 End Property

 Private Sub New()
 End Sub

 Public Sub New(container As IContainer)
  'container.Add(Me, "TextArray1")
  container.Add(Me)
 End Sub

'以下割愛

End Class
引用返信 編集キー/
■95251 / inTopicNo.6)  Re[5]: Component内で自身のname
□投稿者/ 殿下 (4回)-(2020/07/03(Fri) 16:27:30)
No95239 (魔界の仮面弁士 さん) に返信

Site.Name でコンポーネントのnameが参照できました。

実行時には、SiteがNothingだったので、無いと思ったようでした。
デザイン時には値が入ってることを確認できました。
解決済み
引用返信 編集キー/
■95252 / inTopicNo.7)  Re[6]: Component内で自身のname
□投稿者/ 魔界の仮面弁士 (2773回)-(2020/07/03(Fri) 18:17:45)
2020/07/03(Fri) 18:23:37 編集(投稿者)

No95251 (殿下 さん) に返信
> Site.Name でコンポーネントのnameが参照できました。
> 実行時には、SiteがNothingだったので、無いと思ったようでした。

Public Sub New(container As IContainer)
のコンストラクタ定義が鍵となります。


このコンストラクタを用意しておかないと、Site プロパティや GetService(Type) メソッドが
既定で Nothing を返すことになります。

なお、通常は引数無しのコンストラクタも残しておくのですが、
Name 未設定だと今回の要件を満たせなくなるため、
No95239 ではあえて、引数無しの方を Private (あるいは未実装)にしています。
Public のままにしておいても、直ちに動作に影響があるわけではないですけれど。



【IContainer を受け取るコンストラクタを持つ Component 継承クラスの例】
 System.Windows.Forms.Timer
 System.Windows.Forms.ErrorProvide
 System.Windows.Forms.ToolTip
 System.Windows.Forms.BindingSource
 System.IO.Ports.SerialPort
 Microsoft.VisualBasic.Compatibility.VB6.TextBoxArray


【IContainer を受け取るコンストラクタを持たない Component 継承クラスの例】
 System.Timers.Timer
 System.Data.DataSet
 System.DirectoryServices.DirectoryEntry
 System.Drawing.Printing.PrintDocument
 System.ComponentModel.BackgroundWorker
 System.Windows.Forms.OpenFileDialog


関連情報

http://www.ailight.jp/Blog/kazuk/archive/2006/4/13/%E3%83%87%E3%82%B6%E3%82%A4%E3%83%8A%E3%81%A7%E7%94%9F%E6%88%90%E3%81%95%E3%82%8C%E3%81%9F%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AF%E4%BF%A1%E7%94%A8%E3%81%97%E3%81%A1%E3%82%83%E3%81%84%E3%81%91%E3%81%AA%E3%81%84
http://www.ailight.jp/Blog/kazuk/archive/2006/5/28/SystemComponentModel%20%E3%81%AF%E3%81%99%E3%81%A7%E3%81%AB%E6%AD%BB%E3%82%93%E3%81%A0%E3%80%81IDisposable%E3%82%82%E6%AD%BB%E3%81%AB%E3%81%A4%E3%81%A4%E3%81%82%E3%82%8B
解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


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

このトピックに書きこむ