【发布时间】:2010-10-22 18:30:39
【问题描述】:
我有一个 WinForm TreeView 控件,它显示 CaseNotes 的父子关系(我知道这对你们大多数人来说毫无意义,但它可以帮助我将答案可视化)。
我有一个需要显示的 CaseNotes 的数据表。 Parent/Child 定义为:如果行有 ParentNoteID,那么它是该注释的 childNode,否则它是 rootNode。如果另一行的 ID 与 ParentNoteID 相同,它也可能是父注释(但不是根节点)。
为了使事情复杂化(也许是简化),我有下面的工作(大部分)代码交替着色节点。我为树视图手动创建了一个静态集合,它为它们着色相当正确。现在我需要从我的 DataTable 中动态填充节点。
既然我已经逐个节点地遍历树视图,我不应该能够以某种方式将数据附加到这个过程中吗?也许我需要先构建节点,然后将颜色作为一个单独的例程,但递归方法仍然适用,对吗?
假设我想为每个节点显示 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
所以我找到了这个链接,here,这让我觉得我需要将我的 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...
【问题讨论】:
-
关于“编辑 2” - 不,这不是必需的,只要您可以执行自己的逻辑来管理数据结构中的迭代。
-
关于“编辑 3” - 我的那部分代码用于构建一个包含示例数据的示例表,以确保其正常工作。如果您的 GetAllCNotes 函数返回具有相似结构的 DataTable,那么您可以简单地删除整个 CreateData 函数。
-
谢谢我把它拼凑起来。感谢一切!问题虽然。关于这部分 --> DataRow[] childRows = dt.Select("ParentNoteID = " + dr["NoteID"]);它给了我一个运行时错误,因为它无法通过名称找到一个 COLUMN,但它随后列出了一个值......想法?
-
忽略以上评论。它不会让我出于某种原因删除。请参阅 EDIT 4。谢谢
-
关于“编辑 4” - 您可能需要做一个简单的更改: dt.Select("ParentNoteID = '" + dr["NoteID"] + "'");这会在 NoteID 周围添加一个单引号,表示它是一个字符串(参见 SQL WHERE 子句语法)
标签: c# .net winforms recursion treeview