- 題名: 親の親 祖父クラスに変更を加えたい場合。
- 日時: 2011/10/19 13:10:09
- ID: 29256
- この記事の返信元:
- (なし)
- この記事への返信:
- [29257] Re[1]: 親の親 祖父クラスに変更を加えたい場合。2011/10/19 13:51:14
- [29260] Re[1]: 親の親 祖父クラスに変更を加えたい場合。2011/10/19 14:05:18
- ツリーを表示
■No29256に返信(ろいかえさんの記事)
Public Interface IDataGridViewColumnEx
Property NewProperty As String
End Interface
Public Class DataGridViewTextBoxColumnEX
Inherits DataGridViewTextBoxColumn
Implements IDataGridViewColumnEx
Public Property NewProperty As String Implements IDataGridViewColumnEx.NewProperty
Get
End Get
Set(value As String)
End Set
End Property
End Class
Public Class DataGridViewLinkColumnEx
Inherits DataGridViewLinkColumn
Implements IDataGridViewColumnEx
Public Property NewProperty As String Implements IDataGridViewColumnEx.NewProperty
Get
End Get
Set(value As String)
End Set
End Property
End Class
多重継承はインターフェースで実装です。
■No29266に返信(ろいかえさんの記事)
> なんとかして定義も共有する方法はないのでしょうか…
ちょっと強引ですがExtensionを使用して
呼び出し:
Column1.NewValue.Value = "1"
Column2.NewValue.Value = "2"
Dim a = Column1.NewValue.Value
Dim b = Column2.NewValue.Value
定義:
Imports System.Runtime.CompilerServices
Public Module DataGridViewColumnExMod
Private m_NewValues As Dictionary(Of DataGridViewColumn, clsNewValue) = Nothing
<Extension()>
Public Function NewValue(gcol As DataGridViewColumn) As clsNewValue
Dim Ret As clsNewValue = Nothing
If gcol Is Nothing Then
Return New clsNewValue()
End If
If m_NewValues Is Nothing Then
m_NewValues = New Dictionary(Of DataGridViewColumn, clsNewValue)
Else
m_NewValues.TryGetValue(gcol, Ret)
End If
If Ret Is Nothing Then
Ret = New clsNewValue
m_NewValues.Add(gcol, Ret)
AddHandler gcol.Disposed, AddressOf gcol_disposed
End If
Return Ret
End Function
Private Sub gcol_disposed(sender As Object, e As EventArgs)
m_NewValues.Remove(DirectCast(sender, DataGridViewColumn))
If m_NewValues.Count = 0 Then
m_NewValues = Nothing
End If
End Sub
End Module
Public Class clsNewValue
Public Property Value As String = String.Empty
End Class
■No29270に返信(Azuleanさんの記事)
■No29271に返信(shuさんの記事)
デリゲート、拡張メソッド、どちらも知らない機能だったのでとても勉強になりました。
しかし今回一番参考になったのは、
Public Property Value As String = String.Empty
の1行でプロパティの定義ができるということです。
プロパティの中身を書かなくても、自動的に
Private _NewProperty As String
Public Property NewProperty() As String
Get
Return _NewProperty
End Get
Set(ByVal value As String)
_NewProperty = value
End Set
End Property
のような処理をしてくれるということを今まで知りませんでした。
これならばプロパティの内部処理を間違って書くことがないので、
単純な取得と設定だけのプロパティは以下のように1行で書くことに致します。
Public Interface IDataGridViewColumnEx
Property NewProperty As String
End Interface
Public Class DataGridViewTextBoxColumnEx
Inherits DataGridViewTextBoxColumn
Implements IDataGridViewColumnEx
Public Property NewProperty As String = String.Empty Implements IDataGridViewColumnEx.NewProperty
End Class
Public Class DataGridViewLinkColumnEx
Inherits DataGridViewLinkColumn
Implements IDataGridViewColumnEx
Public Property NewProperty As String = String.Empty Implements IDataGridViewColumnEx.NewProperty
End Class
問題はプロパティ内で別のメソッドや変数にアクセスするような場合は1行で書けないので、
Azuleanさんやshuさんに提示していただいた方法を使うことになります。
拡張メソッドについては、調べて大体把握したのですが、
(この場合は拡張メソッドで値保持用クラスのインスタンスを取得して、値保持用クラスのプロパティにアクセスする方法ですね)
デリゲートについては、プロパティが委譲できないらしいので、どこをデリゲートして良いのかわかりません;
(いろんな構造を考えたのですが、どうしてもNewPropertyを共有化させる方法が思いつきません)
分類:[.NET]
クラスの継承階層が以下のようになっている場合、目的の動作を行うにはどうしたら良いでしょうか? AAA.BBB ← ここに影響を加える AAA.BBB.CCC AAA.BBB.CCC.DDD ← ここに反映させたい AAA.BBB.CCC.EEE ← ここに反映させたい AAA.BBB.CCC.FFF ← ここに反映させたい 具体的にどういう状況かと言いますと、 データグリッドビューのカラムである、 DataGridViewColumnというクラスがあります。 さらにそれを継承した、 DataGridViewTextBoxColumn DataGridViewLinkColumn DataGridViewButtonColumn などのクラスが標準で用意されています。 DataGridViewColumnを継承した全てのカラムに新しいプロパティを追加したかったので、 DataGridViewColumnクラスを継承した、以下のようなクラスを作成しました。 Public Class DataGridViewColumnEX Inherits DataGridViewColumn Private newPropertyValue As String Public Property NewProperty() As String Get Return newPropertyValue End Get Set(ByVal value As String) newPropertyValue = value End Set End Property End Class そしていざ、このNewPropertyが追加されたDataGridViewTextBoxColumnを作ろうと思ったのですが、 以下のような問題が発生しました。 Public Class DataGridViewTextBoxColumnEX 'Inherits DataGridViewColumnEX ' ←これを継承しないとNewPropertyが追加されない。 'Inherits DataGridViewTextBoxColumn '←これを継承しないとテキストボックス型のカラムにならない。 End Class さらに、上記の問題が解決した場合、NewPropertyを参照するために、 DataGridViewを継承したクラスでColumnsプロパティを使って、 Me.Columns(0).NewPropertyのように参照したいのですが、 DataGridView.ColumnsプロパティはDataGridViewColumn型を格納しているDataGridViewColumnCollection型のため、 新しく作成したNewPropertyを参照することができません。 これを解決するにはおそらく、DataGridViewColumnEX型を格納するDataGridViewColumnCollectionEXが必要になると思います。 プロパティを1つ追加するだけで大変な作業が必要なようです; まとめとして、以下のような構造を目指しています。 'ColumnsプロパティをDataGridViewColumnCollectionEX型にしなければならない。 Public Class DataGridViewEX Inherits DataGridView End Class 'Itemの型をDataGridViewColumnEX型にしなければならない。 Public Class DataGridViewColumnCollectionEX Inherits DataGridViewColumnCollection Public Sub New(ByVal _parentDataGridView As DataGridViewEX) MyBase.New(_parentDataGridView) End Sub End Class 'このクラスは多分これで良い。 Public Class DataGridViewColumnEX Inherits DataGridViewColumn Private newPropertyValue As String Public Property NewProperty() As String Get Return newPropertyValue End Get Set(ByVal value As String) newPropertyValue = value End Set End Property End Class '継承したいクラスが複数ある。 Public Class DataGridViewTextBoxColumnEX 'Inherits DataGridViewColumnEX 'Inherits DataGridViewTextBoxColumn End Class