DOBON.NET DOBON.NETプログラミング掲示板過去ログ

checkbox付きのTreeViewで選択された項目を取得したい

環境/言語:[C#2008 .NET ver3.5]
分類:[.NET]

C#2008でXML形式のデータを読み込ませてTreeView上に表示させています。
TreeViewにはcheckboxを付けており、ツリー全体からチェックされている項目名を
すべて取得してtextboxに表示させるという事をやりたいのですが、やり方がわかりません。foreach


※XMLデータの方は下記のような構造で、「チェックされているitemタグの項目」を抽出したいのです。(group タグ項目は必要ありません)

<root name=" 会社" ward="">
<group name=" 日本" ward="">
<group name=" 東京本社" ward="tokyo" section="">
<group name=" 営業部" ward="tokyo" section="eigyo">
<item name=" 営業1課" ward="tokyo" section="eigyo"/>
<item name=" 営業2課" ward="tokyo" section="eigyo"/>
<item name=" 営業3課" ward="tokyo" section="eigyo"/>
</group>
<group name=" 総務部" ward="" section="">
<item name=" 総務1課" ward="tokyo" section="soumu"/>
<item name=" 総務2課" ward="tokyo" section="soumu"/>
<item name=" 総務3課" ward="tokyo" section="soumu"/>
</group>
</group>
</group>
</root>
■No28986に返信(たけぞうさんの記事)
> TreeViewにはcheckboxを付けており、ツリー全体からチェックされている項目名を
> すべて取得してtextboxに表示させるという事をやりたいのですが、やり方がわかりません。

こういうことで良いのかな…。

using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System.Xml.Linq;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        XDocument doc;
        TreeView treeView1 = new TreeView();
        TextBox textBox1 = new TextBox() { Multiline = true, ScrollBars = ScrollBars.Both, Height = 100 };
        
        public Form1()
        {
            doc = XDocument.Parse(
@"<root name='会社' ward=''>
    <group name='日本' ward=''>
        <group name='東京本社' ward='tokyo' section=''>
            <group name='営業部' ward='tokyo' section='eigyo'>
                <item name='営業1課' ward='tokyo' section='eigyo'/>
                <item name='営業2課' ward='tokyo' section='eigyo'/>
                <item name='営業3課' ward='tokyo' section='eigyo'/>
            </group>
            <group name='総務部' ward='' section=''>
                <item name='総務1課' ward='tokyo' section='soumu'/>
                <item name='総務2課' ward='tokyo' section='soumu'/>
                <item name='総務3課' ward='tokyo' section='soumu'/>
            </group>
        </group>
    </group>
</root>");

            InitializeComponent();

            this.Controls.Add(treeView1);
            treeView1.Dock = DockStyle.Fill;
            treeView1.CheckBoxes = true;

            this.Controls.Add(textBox1);
            textBox1.ReadOnly = true;
            textBox1.Dock = DockStyle.Bottom;

            treeView1.Nodes.Add(new TakezoNode(doc.Root));
            treeView1.ExpandAll();

            treeView1.AfterCheck += delegate(object sender, TreeViewEventArgs e)
            {
                textBox1.Clear();
                Sample(treeView1.Nodes.OfType<TakezoNode>());
            };

            treeView1.AfterCheck += delegate(object sender, TreeViewEventArgs e)
            {
                foreach (TreeNode node in e.Node.Nodes)
                {
                    node.Checked = e.Node.Checked;
                }
            };
        }

        void Sample(IEnumerable<TakezoNode> nodes)
        {
            foreach (var item in nodes)
            {
                if (item.Checked && item.Xml.Name == "item") 
                {
                    textBox1.AppendText(item.Xml.ToString() + "\r\n");
                }
                Sample(item.Nodes.OfType<TakezoNode>());
            }
        }

        class TakezoNode : TreeNode
        {
            public readonly XElement Xml;
            public TakezoNode(XElement element)
            {
                this.Xml = element;
                this.Text = element.Attribute("name").Value;
                this.ForeColor = (element.Name == "item") ? Color.Blue : Color.Brown;

                foreach (var child in element.Elements())
                {
                    this.Nodes.Add(new TakezoNode(child));
                }
            }
        }
    }
}
魔界の仮面弁士さん

ありがとうございます。
まさにやりたい事そのままの回答頂けました。

Nodeからの値の取得方法など勉強になりました。
本当にありがとうございます!!




■No28989に返信(魔界の仮面弁士さんの記事)
> ■No28986に返信(たけぞうさんの記事)
>>TreeViewにはcheckboxを付けており、ツリー全体からチェックされている項目名を
>>すべて取得してtextboxに表示させるという事をやりたいのですが、やり方がわかりません。
>
> こういうことで良いのかな…。
>
> using System.Collections.Generic;
> using System.Drawing;
> using System.Linq;
> using System.Windows.Forms;
> using System.Xml.Linq;
>
> namespace WindowsFormsApplication1
> {
> public partial class Form1 : Form
> {
> XDocument doc;
> TreeView treeView1 = new TreeView();
> TextBox textBox1 = new TextBox() { Multiline = true, ScrollBars = ScrollBars.Both, Height = 100 };
>
> public Form1()
> {
> doc = XDocument.Parse(
> @"<root name='会社' ward=''>
> <group name='日本' ward=''>
> <group name='東京本社' ward='tokyo' section=''>
> <group name='営業部' ward='tokyo' section='eigyo'>
> <item name='営業1課' ward='tokyo' section='eigyo'/>
> <item name='営業2課' ward='tokyo' section='eigyo'/>
> <item name='営業3課' ward='tokyo' section='eigyo'/>
> </group>
> <group name='総務部' ward='' section=''>
> <item name='総務1課' ward='tokyo' section='soumu'/>
> <item name='総務2課' ward='tokyo' section='soumu'/>
> <item name='総務3課' ward='tokyo' section='soumu'/>
> </group>
> </group>
> </group>
> </root>");
>
> InitializeComponent();
>
> this.Controls.Add(treeView1);
> treeView1.Dock = DockStyle.Fill;
> treeView1.CheckBoxes = true;
>
> this.Controls.Add(textBox1);
> textBox1.ReadOnly = true;
> textBox1.Dock = DockStyle.Bottom;
>
> treeView1.Nodes.Add(new TakezoNode(doc.Root));
> treeView1.ExpandAll();
>
> treeView1.AfterCheck += delegate(object sender, TreeViewEventArgs e)
> {
> textBox1.Clear();
> Sample(treeView1.Nodes.OfType<TakezoNode>());
> };
>
> treeView1.AfterCheck += delegate(object sender, TreeViewEventArgs e)
> {
> foreach (TreeNode node in e.Node.Nodes)
> {
> node.Checked = e.Node.Checked;
> }
> };
> }
>
> void Sample(IEnumerable<TakezoNode> nodes)
> {
> foreach (var item in nodes)
> {
> if (item.Checked && item.Xml.Name == "item")
> {
> textBox1.AppendText(item.Xml.ToString() + "\r\n");
> }
> Sample(item.Nodes.OfType<TakezoNode>());
> }
> }
>
> class TakezoNode : TreeNode
> {
> public readonly XElement Xml;
> public TakezoNode(XElement element)
> {
> this.Xml = element;
> this.Text = element.Attribute("name").Value;
> this.ForeColor = (element.Name == "item") ? Color.Blue : Color.Brown;
>
> foreach (var child in element.Elements())
> {
> this.Nodes.Add(new TakezoNode(child));
> }
> }
> }
> }
> }
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板