当我使用WPF DataGrid时(我假设SL版本的工作方式类似),并且我在运行时指定列(即它们在编译时不可知,因此通过Reflection自动生成列不起作用) )
如何提供项目以便它们在网格中正确显示?换句话说,给定以下DataGrid:
<DataGrid x:Name="dataGrid" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Foo"/>
<DataGridTextColumn Header="Bar"/>
<DataGridTextColumn Header="Baz"/>
</DataGrid.Columns>
</DataGrid>
我尝试了以下内容:
dataGrid.Items.Add(new[] {"a1", "a2", "a3"});
dataGrid.Items.Add(new[] {"b1", "b2", "b3"});
和
dataGrid.Items.Add(new Dictionary<string, string>() {
{"Foo", "a1"},
{"Bar", "a2"},
{"Baz", "a3"},
});
dataGrid.Items.Add(new Dictionary<string, string>() {
{"Foo", "b1"},
{"Bar", "b2"},
{"Baz", "b3"},
});
请注意,尽管在我的示例中列是在Xaml中定义的并且是静态的,但对于我的应用程序,它们不在Xaml中并且将在运行时生成(所以我不能只是创建一个具有属性“Foo”,“Bar”,“Baz”)
的类答案 0 :(得分:1)
您最好的选择可能是以实现ICustomTypeDescriptor
的类的形式展示您的项目。这样,您可以根据需要动态添加属性,DataGrid
会自动选择它们(如果您将AutoGenerateColumns
设置回true
)。
另一种选择是使用ExpandoObject
,但DataGrid
将无法自动检测属性。但是,如果您手动创建列,则可以使用它:
dg.Columns.Add(new DataGridTextColumn { Header = "Foo", Binding = new Binding("Foo") });
dg.Columns.Add(new DataGridTextColumn { Header = "Bar", Binding = new Binding("Bar") });
dg.Columns.Add(new DataGridTextColumn { Header = "Baz", Binding = new Binding("Baz") });
dynamic x = new ExpandoObject();
x.Foo = 42;
x.Bar = "Hello";
x.Baz = DateTime.Today;
dg.Items.Add(x);
x = new ExpandoObject();
x.Foo = 0;
x.Bar = "zzz";
x.Baz = DateTime.MinValue;
dg.Items.Add(x);
编辑:实际上,我意识到你可能在编译时不知道属性的名称,所以ExpandoObject
对你不起作用。相反,您可以使用我在this blog post中发布的示例类,并添加方法以按名称访问属性:
public class MyDynamicObject : DynamicObject
{
private Dictionary<string, object> _properties = new Dictionary<string, object>();
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
return _properties.TryGetValue(binder.Name, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
_properties[binder.Name] = value;
return true;
}
public void SetProperty(string name, object value)
{
_properties[name] = value;
}
public object GetProperty(string name)
{
return _properties[name];
}
}
EDIT2:我刚刚意识到我忘记了另一个非常简单的方法:使用DataTable
。它很容易设置,DataGrid
将能够自动生成列。