前段時間,項目((C#)winfrom)中有用到treeview控件,一開始,想到的就是使用XML加載數據源了,看了幾天MSDN(以前不太用treeview控件和XML),然后開始寫代碼,但XML很是復雜,但基本的增刪改查還是學的差不多了。
好了,現在把我寫的代碼先一步一步貼出來。
我先寫了一個函數,是實現對Xmldocument文檔的調用,便於其他諸如增、刪、改、查的對xmldocument文檔的調用。
/// <summary>
/// 創建XML函數
/// </summary>
/// <returns></returns>
private XmlDocument GetPath()
{
XmlDocument Xmldoc = new XmlDocument();
string path = AppDomain.CurrentDomain.BaseDirectory + "AreaName.xml";
Xmldoc.Load(path);
return Xmldoc;
}
初始化打開winfrom窗體的時候,加載下面的函數。——查詢函數,把XML文檔的數據綁定到treeview,生成一顆節點樹。
/// <summary>
/// 綁定XML到treeview
/// </summary>
private void AddTreeView()
{
try
{
XmlDocument xmlDoc = GetPath();
//禁止重繪
tree_Area.BeginUpdate();
XmlElement xe = (XmlElement)xmlDoc.SelectSingleNode("root");
//綁定屬性節點到treeview
TreeNode root = new TreeNode();
root.Name = xe.GetAttribute("name");
root.Text = xe.GetAttribute("value");
root = GetChildNodes(xe, root);
tree_Area.Nodes.Add(root);
tree_Area.EndUpdate();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
/// <summary>
/// 遞歸遍歷節點
/// </summary>
/// <param name="xe"></param>
/// <param name="upNode"></param>
/// <returns></returns>
private TreeNode GetChildNodes(XmlElement xe, TreeNode upNode)
{
//遞歸遍歷節點
if (xe.HasChildNodes)
{
foreach (XmlNode node in xe.ChildNodes)
{
XmlElement xlt = (XmlElement)node;
TreeNode tn = new TreeNode();
tn.Text = xlt.GetAttribute("name");
tn.Name = xlt.GetAttribute("value");
GetChildNodes(xlt, tn);
upNode.Nodes.Add(tn);
}
}
return upNode;
}
然后是在winfrom界面上添加了2個textbox控件,用於接收來自用戶需要添加到treeview控件的數據。
Add——向treeview控件添加數據。
private void InsertNode()
{
TreeNode SelectNode = null;
TreeNode node = null;
XmlDocument Xmldoc = GetPath();
SelectNode = this.tree_Area.SelectedNode;
node = new TreeNode();
node.Text = txt_Nub.Text.Trim();
node.Name = txt_AreaName.Text.Trim();
if (txt_AreaName.Text != "" && txt_Nub.Text != "")
{
if (txt_AreaName.Text == "" && txt_Nub.Text == "")
{
tree_Area.Nodes.Add(node);
}
else
{
TreeNode ttn = new TreeNode();
ttn.Name = txt_Nub.Text;
ttn.Text = txt_Nub.Text;
tree_Area.Nodes.Add(ttn);
}
}
else
{
MessageBox.Show("請選擇節點或文本框不能為空!");
}
}
Remove——刪除treeview控件的某個Node。
private void DeleteNode()
{
XmlDocument xmlDoc = GetPath();
if (txt_AreaName.Text.Trim() != "" && txt_Nub.Text.Trim() != "")
{
TreeNode selectNode = tree_Area.SelectedNode;
if (selectNode != null)
{
TreeNode parentNode = selectNode.Parent;
if (parentNode == null)
{
//從treeview 的節點集合中刪除當前選中的節點
tree_Area.Nodes.Remove(selectNode);
txt_AreaName.Text = "";
txt_Nub.Text = "";
}
else
{
//從父節點的集合中刪除當前選中的節點
tree_Area.Nodes.Remove(selectNode);
txt_Nub.Text = "";
txt_AreaName.Text = "";
XmlNode root = xmlDoc.SelectSingleNode("root");
XmlNodeList xnl = xmlDoc.SelectSingleNode("root").ChildNodes;
for (int i = 0; i < xnl.Count; i++)
{
XmlElement xe = (XmlElement)xnl.Item(i);
if (xe.GetAttribute("name") == selectNode.Name)
{
root.RemoveChild(xe);
if (i < xnl.Count)
{
i = i - 1;
}
}
}
}
}
else
{
MessageBox.Show("未選中節點或無法刪除父節點!", "提示");
}
}
}
Alter——對treeview控件的數據進行編輯。
private void UpdateNode()
{
if (txt_AreaName.Text.Trim() != "" && txt_Nub.Text.Trim() != "")
{
TreeNode SelectNode = tree_Area.SelectedNode;
SelectNode.Text = txt_AreaName.Text.Trim();
SelectNode.Name = txt_Nub.Text.Trim();
txt_AreaName.Text = SelectNode.Text;
txt_Nub.Text = SelectNode.Name;
txt_AreaName.Text = "";
txt_Nub.Text = "";
}
else
{
MessageBox.Show("請選擇節點或文本框不能為空!");
}
}
上面的函數實現了在winfrom窗體上對treeview控件的增、刪、改、查,但是還不夠,因為做到這一步,也只是實現了在treeview控件上的增刪改查,但是前面說過,還需把改動之后的treeview數據保存到XML文檔里。
下面的函數就能實現把treeview控件的數據寫入XML文檔。
首先得定義好XML文檔的版本、格式等。
XmlTextWriter tw = null;
/// <summary>
/// 把treeview的節點寫入XML文檔
/// </summary>
private void AddXml()
{
string fileName = AppDomain.CurrentDomain.BaseDirectory + "AreaName.xml";
tw = new XmlTextWriter(fileName, null);
//設置寫入的XML文檔格式為縮進
tw.Formatting = Formatting.Indented;
//聲明默認版本 1.0
tw.WriteStartDocument();
//當前獲取到節點
WriteXML(tree_Area.Nodes);
//關閉打開的元素
tw.WriteEndDocument();
//刷新基礎流
tw.Flush();
tw.Close();
}
/// <summary>
/// 遞歸當前treeview節點寫入XML文檔
/// </summary>
/// <param name="tc"></param>
public void WriteXML(TreeNodeCollection tc)
{
foreach (TreeNode Node in tc)
{
WriteOneXML(Node);
WriteXML(Node.Nodes);
//關閉使用過的節點
tw.WriteEndElement();
}
}
/// <summary>
/// 布局元素節點和屬性節點
/// </summary>
/// <param name="Node">treeview節點</param>
private void WriteOneXML(TreeNode Node)
{
string value = Node.Name;
string name = Node.Text;
//根據treeview的節點來寫元素節點
switch (Node.Level)
{
case 0:
tw.WriteStartElement("root");
break;
case 1:
tw.WriteStartElement("province");
break;
case 2:
tw.WriteStartElement("City");
break;
case 3:
tw.WriteStartElement("Piecearea");
break;
case 4:
tw.WriteStartElement("Town");
break;
case 5:
tw.WriteStartElement("Equipmentn");
break;
}
//寫屬性節點
tw.WriteAttributeString("value", value);
tw.WriteAttributeString("name", name);
//...剩余的屬性節點
}
運行后,

寫在結尾:以上我是根據自己的項目來寫的,但是總體還是實現了:1.讀取XML文檔,綁定到treeview控件;2.在窗體上對treeview控件的數據進行編輯,然后回傳XML文檔。
但是,我當前的項目中使用XML作為數據源,在編輯treeview節點之后,回傳到XML文檔的時候,還有些問題,因為我的XML文檔的格式比較復雜點。還有就是有多個地方都使用這個源,所以,當某個地方添加了數據之后,這邊還得需要同步,雖然可以使用類的繼承方式來實現,但現在的時間不允許了。所以還得使用其他的方法。目前使用的數據源是sqlite,這是一款輕型的數據庫。在官方網找了資料看了之后用起來很是方便,如果存儲的數據量在10W以內的話,用起來還是不錯的,最重要的是,當前一些主流數據庫的語法在sqlite上大部分是可以使用的。
我后續還會寫一篇關於使用sqlite來作為treeview控件的數據源的文章。歡迎大家留言/發email一起討論。謝謝! Via cnblogs.com/aehoo/ 2012.02.25
