我有一个WinForm TreeView Control,用于显示CaseNotes的父子关系(我知道这对大多数人来说没有意义,但它可以帮助我理解答案)。
我有一个需要显示的CaseNotes DataTable。 父/子关系定义如下:如果行具有ParentNoteID,则它是该笔记的ChildNode,否则它是rootNode。 如果另一行的ID作为其ParentNoteID,则它也可能是父笔记(但不是rootNode)。
为了使事情变得复杂(也许简单),我已经编写了以下工作代码(大部分)以交替着色节点。 我手动为treeview创建了静态集合,并且它们的颜色相当正确。 现在我需要从我的DataTable动态填充节点。
既然我已经逐个遍历treeview节点,那么我应该能够在此过程中将数据附加到其中,对吗? 也许我需要先构建节点,然后再单独着色作为例行程序,但递归方法仍然适用,对吗?
假设我想为每个节点显示CaseNoteID。 在DataTable中返回并且是唯一的。
所以我找到了这个链接,在这里,看起来像是我需要将我的 DataTable 转换成 ArrayList。这是正确的吗?
编辑3:
好的,多亏了 Cerebus,这基本上是有效的。我只有一个问题:我如何获取这个内容?
我有一个需要显示的CaseNotes DataTable。 父/子关系定义如下:如果行具有ParentNoteID,则它是该笔记的ChildNode,否则它是rootNode。 如果另一行的ID作为其ParentNoteID,则它也可能是父笔记(但不是rootNode)。
为了使事情变得复杂(也许简单),我已经编写了以下工作代码(大部分)以交替着色节点。 我手动为treeview创建了静态集合,并且它们的颜色相当正确。 现在我需要从我的DataTable动态填充节点。
既然我已经逐个遍历treeview节点,那么我应该能够在此过程中将数据附加到其中,对吗? 也许我需要先构建节点,然后再单独着色作为例行程序,但递归方法仍然适用,对吗?
假设我想为每个节点显示CaseNoteID。 在DataTable中返回并且是唯一的。
foreach (TreeNode rootNode in tvwCaseNotes.Nodes)
{
ColorNodes(rootNode, Color.MediumVioletRed, Color.DodgerBlue);
}
protected void ColorNodes(TreeNode root, Color firstColor, Color secondColor)
{
root.ForeColor = root.Index % 2 == 0 ? firstColor : secondColor;
foreach (TreeNode childNode in root.Nodes)
{
Color nextColor = childNode.ForeColor = childNode.Index % 2 == 0 ? firstColor : secondColor;
if (childNode.Nodes.Count > 0)
{
// alternate colors for the next node
if (nextColor == firstColor)
ColorNodes(childNode, secondColor, firstColor);
else
ColorNodes(childNode, firstColor, secondColor);
}
}
}
编辑
我目前的想法/尝试:
public void BuildSummaryView()
{
tvwCaseNotes.Nodes.Clear();
DataTable cNotesForTree = CurrentCaseNote.GetAllCNotes(Program._CurrentPerson.PersonID);
foreach (var cNote in cNotesForTree.Rows)
{
tvwCaseNotes.Nodes.Add(new TreeNode("ContactDate"));
}
FormPaint();
}
显然这是有缺陷的。首先它只是一遍又一遍地显示 ContactDate。虽然它显示了正确次数,但我想要的是ContactDate的值(它是数据库中的列,并在 DataTable 中返回)。其次,我需要添加 ChildNode 逻辑。一个if (node.parentNode = node.CaseNoteID) blah...
编辑2:所以我找到了这个链接,在这里,看起来像是我需要将我的 DataTable 转换成 ArrayList。这是正确的吗?
编辑3:
好的,多亏了 Cerebus,这基本上是有效的。我只有一个问题:我如何获取这个内容?
DataTable cNotesForTree = CurrentCaseNote.GetAllCNotes(Program._CurrentPerson.PersonID);
我该如何使用返回的 DataTable?只需要将其替换这里的内容吗?
dt = new DataTable("CaseNotes");
dt.Columns.Add("NoteID", typeof(string));
dt.Columns.Add("NoteName", typeof(string));
DataColumn dc = new DataColumn("ParentNoteID", typeof(string));
dc.AllowDBNull = true;
dt.Columns.Add(dc);
// Add sample data.
dt.Rows.Add(new string[] { "1", "One", null });
dt.Rows.Add(new string[] { "2", "Two", "1" });
dt.Rows.Add(new string[] { "3", "Three", "2" });
dt.Rows.Add(new string[] { "4", "Four", null });
dt.Rows.Add(new string[] { "5", "Five", "4" });
dt.Rows.Add(new string[] { "6", "Six", null });
dt.Rows.Add(new string[] { "7", "Seven", null });
dt.Rows.Add(new string[] { "8", "Eight", "7" });
dt.Rows.Add(new string[] { "9", "Nine", "8" });
我感到困惑的是,我是否仍需要执行Column.Add和Row.Adds操作?此外,DataColumn应该如何转换为我的实际数据结构?抱歉提出这些非常幼稚的问题,好消息是我再也不必问第二次了。
编辑4
以下代码运行时会出现错误。
if (nodeList.Find(FindNode) == null)
{
DataRow[] childRows = dt.Select("ParentNoteID = " + dr["NoteID"]);
if (childRows.Length > 0)
{
// Recursively call this function for all childRowsl
TreeNode[] childNodes = RecurseRows(childRows);
// Add all childnodes to this node.
node.Nodes.AddRange(childNodes);
}
// Mark this noteID as dirty (already added).
//doneNotes.Add(noteID);
nodeList.Add(node);
}
错误信息为 --> 找不到列[ea8428e4],这是正确的NoteID的前8位(我必须使用Guid)。它是否应该查找该名称的列?因为我正在使用Guid,所以我需要做些什么其他的事情吗?我已将我的代码和您的代码中的所有引用更改为Guid...