FormにTreeVeiwをtreeView1として配置しています。
何をしているかはコメントを参考にしてください。
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { treeView1.Nodes.Clear(); // ラベル部分のみ手動で描画する treeView1.DrawMode = TreeViewDrawMode.OwnerDrawText; // ノードごとには高さが変えられないので、 // 今回は2行分の高さにしておく treeView1.ItemHeight =26; // 仮に今回はお気に入りを登録しています。 // リストに登録しているのは、単に子ノードを複数登録するので // 同じ事を複数回書かずにループで回すためで、実際に使用する時は、 // メソッドを分けた方が良いと思います。 List<TreeNodeText> lst = new List<TreeNodeText>(); lst.Add(new TreeNodeText( "Android Developer\r\n[ http://developer.android.com/ ]")); lst.Add(new TreeNodeText( "MSDN ホームページ\r\n[ http://msdn.microsoft.com/ ]")); lst.Add(new TreeNodeText( "MSDN Code Gallery\r\n[ http://code.msdn.microsoft.com/ ]")); lst.Add(new TreeNodeText( "Eclipse.org home\r\n[ http://www.eclipse.org/ ]")); TreeNode rootNode = treeView1.Nodes.Add("お気に入り"); Graphics graphics = treeView1.CreateGraphics(); Font font = treeView1.Font; foreach (TreeNodeText treeNodeText in lst) { TreeNode node = new TreeNode(); // ノードのタグにTreeNodeTextクラスのインスタンスを登録 node.Tag = treeNodeText; // ラベルの領域幅は文字列の幅で決まるために、複数行中の // 一番幅の広い文字列を仮のラベルとしておく node.Text = MaxWidthString(graphics, font, treeNodeText.TextList); rootNode.Nodes.Add(node); } font.Dispose(); graphics.Dispose(); } private void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs e) { // タグに TreeNodeText のインスタンスが登録されている場合は、 // インスタンスに登録されている文字列を描画し、それ以外は // ラベルに登録されている文字列を描画する // 通常のノードの描画を e.DrawDefault を使ってシステムに任すと、 // 左上に描画されるために、オーナードローしている。 string text = e.Node.Tag == null ? e.Node.Text : ((TreeNodeText)e.Node.Tag).DisplayText; TextRenderer.DrawText( e.Graphics, text, treeView1.Font, e.Bounds, Color.Black, TextFormatFlags.VerticalCenter | TextFormatFlags.Left); } /// <summary> /// 文字列のリストからTreeViewに描画した場合に、 /// 幅が最長の文字列を返します。 /// </summary> /// <param name="graphics">TreeViewのGraphicsオブジェクト</param> /// <param name="font">文字列の描画に使用するTreeViewのフォント</param> /// <param name="list">文字列のリスト</param> /// <returns>最長の文字列</returns> private string MaxWidthString( Graphics graphics, Font font, List<string> list) { int maxWidth = 0; string maxString = string.Empty; foreach (string text in list) { TextRenderer.DrawText( graphics, text, font, new Point(0, 0), Color.Black); Size stringSize = TextRenderer.MeasureText(graphics, text, font); if (maxWidth < stringSize.Width) { maxWidth = stringSize.Width; maxString = text; } } return maxString; } /// <summary> /// TreeViewのタグに登録する情報をラップするクラス /// </summary> class TreeNodeText { private List<string> textList = new List<string>(); public TreeNodeText(string text) { string[] array = text.Split(new string[]{"\r\n","\n"}, StringSplitOptions.RemoveEmptyEntries); foreach(string s in array) textList.Add(s); } // 表示する文字列を各行ごとのリストを返します。 public List<string> TextList { get { return textList; } set { textList = value; } } // 表示する文字列を行ごとに改行を挟む形で返します。 public string DisplayText { get { return string.Join("\r\n", textList.ToArray()); } } } }
以下のように表示されます。
各ノードの高さは、ラベル表示が出来る分をあらかじめ設定しています。
TreeViewのDrawModeをOwnerDrawAllにすれば細かな調整が出来そうですが、+/-ボタンや、ノード間の線の描画、およびインデントの幅等も計算もする必要が出てきそうなので、今回は多少の格好の悪さは我慢しこのようにしました。
0 件のコメント:
コメントを投稿