如何为 ObjectListView 创建动态模型
How to create a dynamic model for ObjectListView
我搜索了好几个小时,要么我的编程方法不对,要么我没有正确的搜索思路...
很久以前,我发现 ObjectListView 是普通 ListView 的一个很好的替代品。我当前项目中的问题:
我没有静态模型class。我有很多不同种类的对象。每种对象都有不同的属性。在我的 ObjectListView 中,我想显示对象的名称及其属性,给定种类的每个对象一行。 (对于一种Object,属性是一样的)
对于我的 ObjectListView 模型,我尝试了以下迷你示例(使用 "num" 和 "txt" 作为 AspactName):
using System.Dynamic;
[...]
private void addItems()
{
dynamic expando = new ExpandoObject();
expando.num = 1;
expando.txt = "Element";
List<ExpandoObject> lst = new List<ExpandoObject>();
lst.Add(expando);
olv.SetObjects(lst);
}
ObjectListView 添加了一个 Row 但不显示 Properties num 和 txt 的文本。
有解决这个问题的想法吗?是否有另一种方法可以使用 ObjectListView 将列表元素(如 Object.Attributes)显示为列?
提前谢谢你。
好的,谢谢克劳斯,在我的脑海中遵循你的想法并再次搜索特殊对象和 ObjectListView 将我指向 AspectGetterDelegates
我第一次找到了有效的解决方案:
添加以下 AspectGetter 委托,ObjectListView 显示我动态生成的属性的信息:
olv.GetColumn(0).AspectGetter = delegate (dynamic er) { return er.Nummer; };
olv.GetColumn(1).AspectGetter = delegate (dynamic er) { return er.Text; };
如果有人遇到同样的问题,这里有两种用于设置和获取 ExpandoObjects 属性的有用方法:
public static void AddProperty(ExpandoObject expando, string propertyName, object propertyValue)
{
var expandoDict = expando as IDictionary<string, object>;
if (expandoDict.ContainsKey(propertyName))
expandoDict[propertyName] = propertyValue;
else
expandoDict.Add(propertyName, propertyValue);
}
public static object GetProperty(ExpandoObject expando, string propertyName)
{
var expandoDict = expando as IDictionary<string, object>;
if (expandoDict.ContainsKey(propertyName))
return expandoDict[propertyName];
else
return null;
}
我认为你的问题是你有一个"lot of objects of different kinds"。
ObjectListView 适用于以下模型对象:
public class user
{
private string name;
private string address;
public user(string name , string address)
{
this.name = name;
this.address= address;
}
public string Name
{
get { return name; }
set { name = value; }
}
public string Address
{
get { return address; }
set { address = value; }
}
}
然后你可以使用对象列表视图:
List<user> users = new List<user>();
users.Add(new user("Me", "address1");
users.Add(new user("You", "address2");
objectListView1.SetObjects(users);
我也是 ObjectListView 的用户,觉得它很好用,但是最近有类似的问题,我有这样的动态对象。事实上,在我的例子中,我根本不知道代码中的 属性 名称,这仅来自数据,而且我不得不展平父子层次结构中的数据。
我的问题在这里:
我的解决方案是使用 OLV 的一个变体,即 DataListView(似乎无法通过 NuGet 使用,但可以从 OLV 网站下载 http://objectlistview.sourceforge.net/cs/download.html)
然后,一旦我将数据存储在动态对象中(就像您一样),我便将其转换为可以绑定到 DataListView 的 DataTable
我的数据存储在:
List<dynamic> allRecords = new List<dynamic>();
//Build my dynamic data here
我将其转换为数据表:
private DataTable GetDataTableFromObject(List<dynamic> allRecords)
{
DataTable dt = new DataTable();
foreach (dynamic record in allRecords)
{
DataRow dr = dt.NewRow();
foreach (dynamic item in record)
{
var prop = (IDictionary<String, Object>)item;
if (!dt.Columns.Contains(prop["Column_name"].ToString())) //Column_Name = Property name
{
dt.Columns.Add(new DataColumn(prop["Column_name"].ToString()));
}
dr[prop["Column_name"].ToString()] = prop["Data"]; //Data = value
}
dt.Rows.Add(dr);
}
return dt;
}
然后我将它添加到 DataListView
this.dataListView1.DataSource = GetDataTableFromObject(allRecords);
this.dataListView1.RebuildColumns();
我搜索了好几个小时,要么我的编程方法不对,要么我没有正确的搜索思路...
很久以前,我发现 ObjectListView 是普通 ListView 的一个很好的替代品。我当前项目中的问题:
我没有静态模型class。我有很多不同种类的对象。每种对象都有不同的属性。在我的 ObjectListView 中,我想显示对象的名称及其属性,给定种类的每个对象一行。 (对于一种Object,属性是一样的)
对于我的 ObjectListView 模型,我尝试了以下迷你示例(使用 "num" 和 "txt" 作为 AspactName):
using System.Dynamic;
[...]
private void addItems()
{
dynamic expando = new ExpandoObject();
expando.num = 1;
expando.txt = "Element";
List<ExpandoObject> lst = new List<ExpandoObject>();
lst.Add(expando);
olv.SetObjects(lst);
}
ObjectListView 添加了一个 Row 但不显示 Properties num 和 txt 的文本。
有解决这个问题的想法吗?是否有另一种方法可以使用 ObjectListView 将列表元素(如 Object.Attributes)显示为列?
提前谢谢你。
好的,谢谢克劳斯,在我的脑海中遵循你的想法并再次搜索特殊对象和 ObjectListView 将我指向 AspectGetterDelegates
我第一次找到了有效的解决方案: 添加以下 AspectGetter 委托,ObjectListView 显示我动态生成的属性的信息:
olv.GetColumn(0).AspectGetter = delegate (dynamic er) { return er.Nummer; };
olv.GetColumn(1).AspectGetter = delegate (dynamic er) { return er.Text; };
如果有人遇到同样的问题,这里有两种用于设置和获取 ExpandoObjects 属性的有用方法:
public static void AddProperty(ExpandoObject expando, string propertyName, object propertyValue)
{
var expandoDict = expando as IDictionary<string, object>;
if (expandoDict.ContainsKey(propertyName))
expandoDict[propertyName] = propertyValue;
else
expandoDict.Add(propertyName, propertyValue);
}
public static object GetProperty(ExpandoObject expando, string propertyName)
{
var expandoDict = expando as IDictionary<string, object>;
if (expandoDict.ContainsKey(propertyName))
return expandoDict[propertyName];
else
return null;
}
我认为你的问题是你有一个"lot of objects of different kinds"。 ObjectListView 适用于以下模型对象:
public class user
{
private string name;
private string address;
public user(string name , string address)
{
this.name = name;
this.address= address;
}
public string Name
{
get { return name; }
set { name = value; }
}
public string Address
{
get { return address; }
set { address = value; }
}
}
然后你可以使用对象列表视图:
List<user> users = new List<user>();
users.Add(new user("Me", "address1");
users.Add(new user("You", "address2");
objectListView1.SetObjects(users);
我也是 ObjectListView 的用户,觉得它很好用,但是最近有类似的问题,我有这样的动态对象。事实上,在我的例子中,我根本不知道代码中的 属性 名称,这仅来自数据,而且我不得不展平父子层次结构中的数据。
我的问题在这里:
我的解决方案是使用 OLV 的一个变体,即 DataListView(似乎无法通过 NuGet 使用,但可以从 OLV 网站下载 http://objectlistview.sourceforge.net/cs/download.html)
然后,一旦我将数据存储在动态对象中(就像您一样),我便将其转换为可以绑定到 DataListView 的 DataTable
我的数据存储在:
List<dynamic> allRecords = new List<dynamic>();
//Build my dynamic data here
我将其转换为数据表:
private DataTable GetDataTableFromObject(List<dynamic> allRecords)
{
DataTable dt = new DataTable();
foreach (dynamic record in allRecords)
{
DataRow dr = dt.NewRow();
foreach (dynamic item in record)
{
var prop = (IDictionary<String, Object>)item;
if (!dt.Columns.Contains(prop["Column_name"].ToString())) //Column_Name = Property name
{
dt.Columns.Add(new DataColumn(prop["Column_name"].ToString()));
}
dr[prop["Column_name"].ToString()] = prop["Data"]; //Data = value
}
dt.Rows.Add(dr);
}
return dt;
}
然后我将它添加到 DataListView
this.dataListView1.DataSource = GetDataTableFromObject(allRecords);
this.dataListView1.RebuildColumns();