TreeNodeを継承したクラスについて

タグの編集
投稿者 ぼろんご  (社会人) 投稿日時 2013/4/6 09:59:33
いつもこのサイトを参考にさせてもらっております。ありがとうございます。


TreeNodeを継承したTreeNodePlusクラスがあります。

Class TreeNodePlus
    Inherits TreeNode
End Class

TreeViewのTreeNodeCollectionにTreeNodePlusオブジェクトをAddしております。

これをTreeView.SelectedNodeなどで取得する場合、直接TreeNodePlus型として取得するには
どういう方法がありますか?
現在は、TreeNode型で取得して毎回DirectCastで型変換しています。
思いつくのはTreeViewの継承クラスを作り、 型変換して返すメソッドを追加する方法くらいです。

そもそも、TreeView.Nodes.Addメソッドの引数にTreeNode型でなくTreeNodePlus型オブジェクトを
指定するのは問題ないのでしょうか?

投稿者 るきお  (社会人) 投稿日時 2013/4/6 13:01:37
>現在は、TreeNode型で取得して毎回DirectCastで型変換しています。
それが普通です。

>思いつくのは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 IntegerAs 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型オブジェクトを
>>指定するのは問題ないのでしょうか?
>間違いではありません。
問題なく動くけど正しい方法なのかなと疑問に思っていましたので安心しました。


おかげで疑問が解消され、新しい知識も増えました。
回答も丁寧で非常にわかりやすかったです。
ありがとうございました。