C# treeView 複選(checkbox)+Timer 使用遞迴方式達到狀態控制和取出最後子節點的選取狀態並且即時記錄(程式下次開啟具有還原功能) 範例
C# treeView 複選(checkbox)+Timer 使用遞迴方式達到狀態控制和取出最後子節點的選取狀態並且即時記錄(程式下次開啟具有還原功能) 範例
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.IO;
namespace CS_treeView_checkbox_dynamic4F
{
public partial class Form1 : Form
{
private int m_intLevel;//treeview階數
private ArrayList m_ALget = new ArrayList();//取出節點的存放空間
private ArrayList m_ALposition = new ArrayList();
private ArrayList m_ALadd = new ArrayList();//增加節點的存放空間
private bool m_blnOpenLog;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
m_blnOpenLog = false;
string strbuf;
/*
m_intLevel = 1;
for (int i = 0; i < 7; i++)
{
strbuf = “C” + i;
newNode = new TreeNode(strbuf);
treeView1.Nodes.Add(newNode);
}
//*/
/*
m_intLevel = 2;
for (int i = 0; i < 1000; i++)
{
strbuf = “F” + i;
newNode = new TreeNode(strbuf);
treeView1.Nodes.Add(newNode);
}
for (int j = 0; j < treeView1.Nodes.Count; j++)
{
for (int k = 0; k < 70; k++)
{
strbuf = “C” + j + “~” + k;
newNode = new TreeNode(strbuf);
treeView1.Nodes[j].Nodes.Add(newNode);
}
}
//*/
/*
m_intLevel = 3;
for (int i = 0; i < 2; i++)
{
strbuf = “G” + i;
newNode = new TreeNode(strbuf);
treeView1.Nodes.Add(newNode);
}
for (int j = 0; j < treeView1.Nodes.Count; j++)
{
for (int k = 0; k < 4; k++)
{
strbuf = “F” + j + “~” + k;
newNode = new TreeNode(strbuf);
treeView1.Nodes[j].Nodes.Add(newNode);
}
}
for (int j = 0; j < treeView1.Nodes.Count; j++)//F(4)
{
//int k = 0;
int i = 0;
foreach (TreeNode myNode in treeView1.Nodes[j].Nodes)
{
i++;
for (int k = 0; k < 3; k++)
{
strbuf = “C”+myNode.Text.Substring(1) + “~” + k;
newNode = new TreeNode(strbuf);
myNode.Nodes.Add(newNode);
}
}
}
//*/
//*
m_intLevel = 4;
m_ALadd.Clear();
for (int i = 0; i < 2; i++)
{
strbuf = “R” + i;
m_ALadd.Add(strbuf);
//newNode = new TreeNode(strbuf);
//treeView1.Nodes.Add(newNode);
}
AddData(treeView1);
for (int i = 0; i < treeView1.Nodes.Count; i++)
{
m_ALadd.Clear();
TreeNode RTreeNode=treeView1.Nodes[i];
for (int j = 0; j < 4; j++)
{
strbuf = “G” + i + “~” + j;
m_ALadd.Add(strbuf);
//newNode = new TreeNode(strbuf);
//RTreeNode.Nodes.Add(newNode);
}
AddData(RTreeNode);
}
for (int j = 0; j < treeView1.Nodes.Count; j++)
{
foreach (TreeNode GNode in treeView1.Nodes[j].Nodes)
{
m_ALadd.Clear();
for (int k = 0; k < 2; k++)
{
strbuf = “F” + GNode.Text.Substring(1) + “~” + k;
m_ALadd.Add(strbuf);
//newNode = new TreeNode(strbuf);
//GNode.Nodes.Add(newNode);
}
AddData(GNode);
}
}
for (int j = 0; j < treeView1.Nodes.Count; j++)
{
foreach (TreeNode GNode in treeView1.Nodes[j].Nodes)
{
for(int i=0;i<(GNode.Nodes.Count-1);i++)//foreach (TreeNode FNode in GNode.Nodes)
{
m_ALadd.Clear();
TreeNode FNode = GNode.Nodes[i];
for (int k = 0; k < 2; k++)
{
strbuf = “C” + FNode.Text.Substring(1) + “~” + k;
m_ALadd.Add(strbuf);
//newNode = new TreeNode(strbuf);
//FNode.Nodes.Add(newNode);
}
AddData(FNode);
}
}
}
//*/
}
private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{
}
private void AddData(TreeView TV)//TreeView增加根節點
{
String StrBuf;
for (int i = 0; i < m_ALadd.Count; i++)
{
StrBuf = “” + m_ALadd[i];
TV.Nodes.Add(StrBuf);
}
}
private void AddData(TreeNode currNode)//TreeView增加節點
{
String StrBuf;
for (int i = 0; i < m_ALadd.Count; i++)
{
StrBuf = “”+m_ALadd[i];
currNode.Nodes.Add(StrBuf);
}
}
private void SetChildNodeCheckedState(TreeNode currNode, bool isCheckedOrNot)//設置子節點狀態
{
//http://www.cnblogs.com/luxiaoxun/p/3288003.html
if (currNode.Nodes.Count == 0)//沒有子節點返回
{
if (isCheckedOrNot)
{
currNode.BackColor = Color.Yellow;
}
else
{
currNode.BackColor = Color.White;
}
return;
}
foreach (TreeNode tmpNode in currNode.Nodes)
{
if (isCheckedOrNot)
{
currNode.BackColor = Color.Red;
}
else
{
currNode.BackColor = Color.White;
}
tmpNode.Checked = isCheckedOrNot;
SetChildNodeCheckedState(tmpNode, isCheckedOrNot);
}
}
private void SetParentNodeCheckedState(TreeNode currNode, bool isCheckedOrNot)//設置父節點狀態
{
//http://www.cnblogs.com/luxiaoxun/p/3288003.html
if (currNode.Parent == null)//沒有父節點返回
return;
if (isCheckedOrNot) //如果當前節點被選中,則設置所有父節點都被選中
{
//–
bool checkedFlag = true;
foreach (TreeNode tmpNode in currNode.Parent.Nodes)//當前節點的所有同層節點
{
if (tmpNode.Checked == false)
{
checkedFlag = false;
break;
}
}
if (checkedFlag)
{
currNode.Parent.BackColor = Color.Red;
}
else
{
currNode.Parent.BackColor = Color.Yellow;
}
//–
currNode.Parent.Checked = isCheckedOrNot;
SetParentNodeCheckedState(currNode.Parent, isCheckedOrNot);
}
else //如果當前節點沒有被選中,則當其父節點的子節點有一個被選中時,父節點被選中,否則父節點不被選中
{
bool checkedFlag = false;
foreach (TreeNode tmpNode in currNode.Parent.Nodes)
{
if (tmpNode.Checked)
{
checkedFlag = true;
break;
}
}
//–
if (checkedFlag)
{
currNode.Parent.BackColor = Color.Yellow;
}
else
{
currNode.Parent.BackColor = Color.White;
}
//–
currNode.Parent.Checked = checkedFlag;
SetParentNodeCheckedState(currNode.Parent, checkedFlag);
}
}
private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
{
if (e.Action == TreeViewAction.ByMouse || e.Action == TreeViewAction.ByKeyboard)
{
//http://www.cnblogs.com/luxiaoxun/p/3288003.html
SetChildNodeCheckedState(e.Node, e.Node.Checked);
SetParentNodeCheckedState(e.Node, e.Node.Checked);
}
getData(treeView1);
}
private void getData(TreeView TV)//必須從ROOT開始搜尋,所以要傳遞TreeView
{
m_ALget.Clear();
m_ALposition.Clear();
int j=0;
foreach (TreeNode Node in TV.Nodes)
{
String StrPosition = “” + j;
getData(Node, StrPosition);
j++;
}
richTextBox1.Text = “”;
for (int i = 0; i < m_ALget.Count; i++)
{
richTextBox1.Text += m_ALget[i]+”, “;
}
}
private void getData(TreeNode currNode,String StrPosition)//搜尋最後節點的遞迴函數
{
if (currNode.Nodes.Count == 0)//沒有子節點返回
{
if ((currNode.Checked==true) && (currNode.Text.Substring(0,1)==”C”) )
{
String Buf = StrPosition;
m_ALposition.Add(Buf);
m_ALget.Add(currNode.Text + “(” + Buf + “)”);
}
return;
}
else
{
foreach (TreeNode Node in currNode.Nodes)
{
String Buf=StrPosition + “,” + Node.Index;
getData(Node, Buf);
}
}
}
private void timer1_Tick(object sender, EventArgs e)
{
timer1.Enabled=false;
if (System.IO.File.Exists(“AutoSave.dat”) && (!m_blnOpenLog))
{
//有
StreamReader sr = new StreamReader(“AutoSave.dat”);
while (!sr.EndOfStream)// 每次讀取一行,直到檔尾
{
string line = sr.ReadLine();// 讀取文字到 line 變數
string[] strs = line.Split(‘,’);
if (strs.Length > 0)
{
int root = Int32.Parse(strs[0]);
TreeNode RootNode = treeView1.Nodes[root];
TreeNode TmpNode;
for (int i = 1; i < (strs.Length); i++)
{
int j = Int32.Parse(strs[i]);
TmpNode = RootNode.Nodes[j];
RootNode = TmpNode;
}
RootNode.Checked = true;
SetParentNodeCheckedState(RootNode, RootNode.Checked);
//treeView1.SelectedNode = RootNode.Parent;//展開特定節點
//treeView1.SelectedNode.Expand();
}
}
//treeView1.ExpandAll();//打開所有節點
//setUI();
sr.Close();// 關閉串流
}
else
{
timer1.Interval = 1000;//1S
int countIndex = 0;
String selectedNode = “”;
StreamWriter sw = new StreamWriter(“AutoSave.dat”);
for (int i = 0; i < m_ALposition.Count; i++)
{
selectedNode = “” + m_ALposition[i];
sw.WriteLine(selectedNode);// 寫入文字
}
sw.Close();// 關閉串流
}
m_blnOpenLog = true;
timer1.Enabled=true;
}
}
}