c# - 如何将数据表转换为树视图
问题描述
我有一个类似于下面的数据表:
col1 col2 col3 col4 col5 col6
name jack joe will jack joe will
age 12 5 15 12 16 9
origin US It SA Jap Ven Fr
我想从这个表中得到一个类似于下面的树视图:
jack
|_ 12
|_ US
|_ Jap
joe
|_ 5
| |_ It
|_ 16
|_ Ven
will
|_ 15
| |_ SA
|_ 9
|_ Fr
该表可能具有或多或少的列数和行数。
要构建树视图,我有一个自定义节点类,如下所示:
public class Node : PropertyChangedBase
{
private ObservableCollection<Node> mChildren;
// Add all of the properties of a node here. In this example,
// all we have is a name and whether we are expanded.
public string Name
{
get { return _name; }
set
{
if (_name != value)
{
_name = value;
NotifyOfPropertyChange(() => Name);
}
}
}
private string _name;
public bool IsExpanded
{
get { return _isExpanded; }
set
{
if (_isExpanded != value)
{
_isExpanded = value;
NotifyOfPropertyChange(() => IsExpanded);
}
}
}
private bool _isExpanded;
// Children are required to use this in a TreeView
public IList<Node> Children { get { return mChildren; } }
// Parent is optional. Include if you need to climb the tree
// from code. Not usually necessary.
public Node Parent { get; private set; }
public Node(Node parent = null)
{
mChildren = new ObservableCollection<Node>();
IsExpanded = true;
Parent = parent;
}
}
这就是我向树中添加节点的方式:
mRootNodes = new ObservableCollection<Node>();
// Test data for example purposes
Node root = new Node() { Name = "Root" };
Node a = new Node(root) { Name = "Node A" };
root.Children.Add(a);
Node b = new Node(root) { Name = "Node B" };
root.Children.Add(b);
Node c = new Node(b) { Name = "Node C" };
b.Children.Add(c);
Node d = new Node(b) { Name = "Node D" };
b.Children.Add(d);
Node e = new Node(root) { Name = "Node E" };
root.Children.Add(e);
mRootNodes.Add(root);
为此,我得到以下树:
root
Node A
Node B
Node C
Node D
Node E
我怎样才能在 C# 中做到这一点?
任何评论表示赞赏。
解决方案
假如说:
- 每列数据代表新的(或现有的)节点
例如:
if
jack
inrow[0]
=>col1
andcol4
指的是同一个节点
12
在row[1]
=>col1
和col4
指的是同一个节点(的Jack
)等等...
- 数据表中的每一行代表另一个级别的节点......
那么您需要遍历列和行以将数据转换为Node
's 列表。
注意:在下面的示例中,我使用的是List<Node>
代替ObservableCollection<Node>()
,但这应该给你一个想法......
这是一个Node
类定义:
class Node
{
public string Name{get; set;}
public List<Node> Children {get; set;}
}
注意:Parent
由于循环引用,我删除了成员。
用法(LinqPad):
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("prop", typeof(string)));
dt.Columns.AddRange(Enumerable.Range(1,6).Select(x=>new DataColumn($"col{x}", typeof(string))).ToArray());
dt.Rows.Add(new object[]{"name", "jack", "joe", "will", "jack", "joe", "will"});
dt.Rows.Add(new object[]{"age", "12", "5", "15", "12", "16", "9"});
dt.Rows.Add(new object[]{"origin", "US", "It", "SA", "Jap", "Ven", "Fr"});
List<Node> nodes = new List<Node>();
for(int c=1; c<dt.Columns.Count; c++)
{
Node parent = null;
Node current = null;
for(int r=0; r<dt.Rows.Count; r++)
{
DataRow dr = dt.Rows[r];
string name = Convert.ToString(dr[c]);
if(parent==null)
{
parent = new Node(){Name = name, Children= new List<Node>()};
current = nodes.Where(x=>x.Name==parent.Name).SingleOrDefault();
if(current==null)
nodes.Add(parent);
else
parent = current;
}
else
{
current = new Node(){Name = name, Children= new List<Node>()};
if(parent.Children.Where(x=>x.Name==current.Name).SingleOrDefault()==null)
parent.Children.Add(current);
else
current = parent.Children.Where(x=>x.Name==current.Name).SingleOrDefault();
parent = current;
}
}
}
nodes.Dump();
在现实世界中,我建议创建助手类......
推荐阅读
- flutter - 如何在flutter bloc中使用数据模型
- postgresql - 按升序对数据进行排序 POSTGRES SQL
- javascript - 角度类型“{}”上不存在属性“长度”
- ios - 在 TableView 的 CellView 中保持循环关闭
- windows - 我可以将控制台输出重定向到仅保留最后一行的文件吗?
- apache-spark - 将 ElasticSearch 中的数据读入 Spark 数据集
- node.js - TypeError: Cannot set property 'sorting' of undefined..这是我尝试在数据库中对我的 id 进行排序时遇到的错误
- javascript - 如何在同一函数内从 AJAX 调用接收数据,
- javascript - How to make an AJAX delete request in a Vue JS component?
- powershell - 创建 Powershell 脚本以增强用户输入