TreeView控件的大尺寸XML元素
本文关键字:XML 元素 控件 TreeView | 更新日期: 2023-09-27 18:25:23
我正在用XML元素填充TreeView控件。
这种方法非常有效。但我的问题是,如果XML文件大小达到20MB以上,我的应用程序就会冻结。有人能帮我优化我的代码吗:
public void PopulateTreeView(string xmlPath)
{
try
{
var settings = new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore, XmlResolver = null };
var doc = new XmlDocument();
using (var sr = new StreamReader(xmlPath))
{
using (var reader = XmlReader.Create(sr, settings))
{
doc.Load(reader);
//Initialize the TreeView control.
treeView1.Nodes.Clear();
treeView1.Invoke((MethodInvoker)(() => treeView1.Nodes.Add(new TreeNode(doc.DocumentElement.Name))));
TreeNode tNode = new TreeNode();
tNode = treeView1.Nodes[0];
// Populate the TreeView with the DOM nodes.
AddNode(doc.DocumentElement, tNode);
}
}
}
catch (XmlException xmlEx)
{
MessageBox.Show(xmlEx.Message, Path.GetFileName(xmlPath));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void AddNode(XmlNode inXmlNode, TreeNode inTreeNode)
{
XmlNode xNode;
TreeNode tNode;
XmlNodeList nodeList;
int i;
// Loop through the XML nodes until the leaf is reached.
// Add the nodes to the TreeView during the looping process.
if (inXmlNode.HasChildNodes)
{
nodeList = inXmlNode.ChildNodes;
for (i = 0; i <= nodeList.Count - 1; i++)
{
xNode = inXmlNode.ChildNodes[i];
inTreeNode.Nodes.Add(new TreeNode(xNode.Name));
tNode = inTreeNode.Nodes[i];
AddNode(xNode, tNode);
}
}
else
{
inTreeNode.Text = (inXmlNode.OuterXml).Trim();
}
}
非常感谢您的帮助!:)
--编辑--
我试着用backgroundWorker来做这件事,但我得到了:
"InvalidOperationException-对此控件执行的操作是从错误的线程调用"
这就是我正在尝试的:
private void frmMain_Load(object sender, EventArgs e)
{
if (!backgroundWorker.IsBusy)
backgroundWorker.RunWorkerAsync();
}
private void backgroundWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
if (worker.CancellationPending)
{
e.Cancel = true;
}
else
{
try
{
// SECTION 1. Create a DOM Document and load the XML data into it.
var settings = new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore, XmlResolver = null };
var doc = new XmlDocument();
using (var sr = new StreamReader(_xmlPath))
{
using (var reader = XmlReader.Create(sr, settings))
{
doc.Load(reader);
// SECTION 2. Initialize the TreeView control.
treeView1.Nodes.Clear();
treeView1.Nodes.Add(new TreeNode(doc.DocumentElement.Name));
TreeNode tNode = new TreeNode();
tNode = treeView1.Nodes[0];
// SECTION 3. Populate the TreeView with the DOM nodes.
AddNode(doc.DocumentElement, tNode);
//treeView1.ExpandAll();
}
}
}
catch (XmlException xmlEx)
{
MessageBox.Show(xmlEx.Message, Path.GetFileName(_xmlPath));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
public void AddNode(XmlNode inXmlNode, TreeNode inTreeNode)
{
XmlNode xNode;
TreeNode tNode;
XmlNodeList nodeList;
int i;
// Loop through the XML nodes until the leaf is reached.
// Add the nodes to the TreeView during the looping process.
if (inXmlNode.HasChildNodes)
{
nodeList = inXmlNode.ChildNodes;
for (i = 0; i <= nodeList.Count - 1; i++)
{
xNode = inXmlNode.ChildNodes[i];
inTreeNode.Nodes.Add(new TreeNode(xNode.Name));
tNode = inTreeNode.Nodes[i];
AddNode(xNode, tNode);
}
}
else
{
// Here you need to pull the data from the XmlNode based on the
// type of node, whether attribute values are required, and so forth.
inTreeNode.Text = (inXmlNode.OuterXml).Trim();
}
}
您需要做三件事。
- 加载开始前,请调用
SuspendLayout();
- 在单独的线程中加载XML以避免GUI锁定
- 使用类似以下示例的方法通过线程更新gui
- 加载完成后,调用
ResumeLayout();
跨线程扩展方法示例:
using System;
using System.Windows.Forms;
public static class ControlExtensions
{
/// <summary>
/// Executes the Action asynchronously on the UI thread, does not block execution on the calling thread.
/// </summary>
/// <param name="control"></param>
/// <param name="code"></param>
public static void UIThread(this Control @this, Action code)
{
if (@this.InvokeRequired)
{
@this.BeginInvoke(code);
}
else
{
code.Invoke();
}
}
}
扩展方法的功劳在于:如何从C#中的另一个线程更新GUI?