TreeNodeを継承したクラスについて
投稿者 るきお  (社会人)
投稿日時
2013/4/6 13:01:37
>現在は、TreeNode型で取得して毎回DirectCastで型変換しています。
それが普通です。
>思いつくのはTreeViewの継承クラスを作り、 型変換して返すメソッドを追加する方法くらいです。
それもありえますが、わざわざこのためだけの継承するのは手間の方が大きいですね。
一案として継承よりはお手軽な拡張メソッドにするという手もあります。
この例は全体をわかりやすくするために1つのファイルに書いていますが、実際にはクラス、モジュールごとにファイルを分けたが方がよいです。
プログラムの全貌や構想次第でどの手を採用すべきか変わると思いますが、最初に書いたように毎回DirectCastする方法が無難で一般的だと思います。
>そもそも、TreeView.Nodes.Addメソッドの引数にTreeNode型でなくTreeNodePlus型オブジェクトを
>指定するのは問題ないのでしょうか?
間違いではありません。
また、もし何かの事情でこのような使い方が許されないのであればTreeNodeクラスは継承できない設計になっているはずなので、そのような事情はないということと類推できます。
このような問題は、TreeViewを作ったマイクロソフトのプログラマー(というか設計者)がどこまで想定してどこまでテストしているかに依存し、こういったマイクロソフト側の事情がある場合MSDNライブラリに記載されています。
TreeNodeCollectionやTreeNodeの説明をざっと見たところは特に注意書きのようなものもないのでやはり大丈夫だと思います。
TreeNodeクラス
http://msdn.microsoft.com/ja-jp/library/system.windows.forms.treenode(v=vs.100).aspx
TreeNodeCollectionクラス
http://msdn.microsoft.com/ja-jp/library/2667e4k1(v=vs.100).aspx
TreeViewクラス
http://msdn.microsoft.com/ja-jp/library/system.windows.forms.treeview(v=vs.100).aspx
しかしながら、継承の利用はプログラムを複雑化する要因になるので、もっとシンプルな代替手段があるかの検討も行った方が良いと思います。
それが普通です。
>思いつくのはTreeViewの継承クラスを作り、 型変換して返すメソッドを追加する方法くらいです。
それもありえますが、わざわざこのためだけの継承するのは手間の方が大きいですね。
一案として継承よりはお手軽な拡張メソッドにするという手もあります。
Option Strict On
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim plus As New TreeNodePlus
plus.CustomMessage = "本日は晴天なり"
TreeView1.Nodes.Add(plus)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim plus As TreeNodePlus = TreeView1.FindTreeNodePlus(0)
MsgBox(plus.CustomMessage)
End Sub
End Class
Public Module TreeViewExtender
<Runtime.CompilerServices.Extension>
Public Function FindTreeNodePlus(source As TreeView, index As Integer) As TreeNodePlus
Dim node = source.Nodes(index)
Return DirectCast(node, TreeNodePlus)
End Function
End Module
Public Class TreeNodePlus
Inherits TreeNode
Public Property CustomMessage As String
Public Sub New()
Me.Text = Now.ToString
End Sub
End Class
この例は全体をわかりやすくするために1つのファイルに書いていますが、実際にはクラス、モジュールごとにファイルを分けたが方がよいです。
プログラムの全貌や構想次第でどの手を採用すべきか変わると思いますが、最初に書いたように毎回DirectCastする方法が無難で一般的だと思います。
>そもそも、TreeView.Nodes.Addメソッドの引数にTreeNode型でなくTreeNodePlus型オブジェクトを
>指定するのは問題ないのでしょうか?
間違いではありません。
また、もし何かの事情でこのような使い方が許されないのであればTreeNodeクラスは継承できない設計になっているはずなので、そのような事情はないということと類推できます。
このような問題は、TreeViewを作ったマイクロソフトのプログラマー(というか設計者)がどこまで想定してどこまでテストしているかに依存し、こういったマイクロソフト側の事情がある場合MSDNライブラリに記載されています。
TreeNodeCollectionやTreeNodeの説明をざっと見たところは特に注意書きのようなものもないのでやはり大丈夫だと思います。
TreeNodeクラス
http://msdn.microsoft.com/ja-jp/library/system.windows.forms.treenode(v=vs.100).aspx
TreeNodeCollectionクラス
http://msdn.microsoft.com/ja-jp/library/2667e4k1(v=vs.100).aspx
TreeViewクラス
http://msdn.microsoft.com/ja-jp/library/system.windows.forms.treeview(v=vs.100).aspx
しかしながら、継承の利用はプログラムを複雑化する要因になるので、もっとシンプルな代替手段があるかの検討も行った方が良いと思います。
投稿者 ぼろんご  (社会人)
投稿日時
2013/4/7 10:51:53
回答ありがとうございます。
>毎回DirectCastする方法が無難で一般的だと思います。
そうなのですね。
独学でやってきたので、こういうとき他の人はどう書くんだろうと疑問に感じたので
今回の質問をさせて頂きました。
>拡張メソッドにするという手もあります
拡張メソッドの存在は知らなかったです。
これから調べてみます。
>>そもそも、TreeView.Nodes.Addメソッドの引数にTreeNode型でなくTreeNodePlus型オブジェクトを
>>指定するのは問題ないのでしょうか?
>間違いではありません。
問題なく動くけど正しい方法なのかなと疑問に思っていましたので安心しました。
おかげで疑問が解消され、新しい知識も増えました。
回答も丁寧で非常にわかりやすかったです。
ありがとうございました。
>毎回DirectCastする方法が無難で一般的だと思います。
そうなのですね。
独学でやってきたので、こういうとき他の人はどう書くんだろうと疑問に感じたので
今回の質問をさせて頂きました。
>拡張メソッドにするという手もあります
拡張メソッドの存在は知らなかったです。
これから調べてみます。
>>そもそも、TreeView.Nodes.Addメソッドの引数にTreeNode型でなくTreeNodePlus型オブジェクトを
>>指定するのは問題ないのでしょうか?
>間違いではありません。
問題なく動くけど正しい方法なのかなと疑問に思っていましたので安心しました。
おかげで疑問が解消され、新しい知識も増えました。
回答も丁寧で非常にわかりやすかったです。
ありがとうございました。
TreeNodeを継承したTreeNodePlusクラスがあります。
Class TreeNodePlus
Inherits TreeNode
End Class
TreeViewのTreeNodeCollectionにTreeNodePlusオブジェクトをAddしております。
これをTreeView.SelectedNodeなどで取得する場合、直接TreeNodePlus型として取得するには
どういう方法がありますか?
現在は、TreeNode型で取得して毎回DirectCastで型変換しています。
思いつくのはTreeViewの継承クラスを作り、 型変換して返すメソッドを追加する方法くらいです。
そもそも、TreeView.Nodes.Addメソッドの引数にTreeNode型でなくTreeNodePlus型オブジェクトを
指定するのは問題ないのでしょうか?