如何添加列表<;列表<;MyClass>>;()作为DataGrid.ItemsSource
本文关键字:列表 lt gt ItemsSource 作为 DataGrid 添加 何添加 MyClass | 更新日期: 2023-09-27 18:00:19
问题
如果我有这样一个列表,我们称之为Rows
,我不想像myDataGrid.ItemsSource = Rows;
那样添加比我在所有列中获得每个子列表的第一个myClass
看起来像
Column0 | Column1 | Column2 | Column3
firstrow0 | firstrow0 | firstrow0 | firstrow0
firstrow1 | firstrow1 | firstrow1 | firstrow1
firstrow2 | firstrow2 | firstrow2 | firstrow2
守则
XAML
<DataGrid Name="myDataGrid" AutoGenerateColumns="False">
<DataGrid.Columns >
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="{x:Type vmv:myClass}">
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="{x:Type vmv:myClass}">
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="{x:Type vmv:myClass}">
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
在后面
var list = new List<List<myClass>>();
for (int row = 0; row < 3; row++)
{
var myRow = new List<myClass>();
for (int col = 0; col < 5; col++)
myRow.Add(new myClass() { ID = col, Name = "Row"+row +" Column:" + col });
list.Add(myRow);
}
myDataGrid.ItemsSource = list.AsEnumerable<IEnumerable>();
myClass
public class myClass
{
public int ID { get; set; }
public string Name { get; set; }
// other stuff
}
问题
我需要什么才能让它工作。我需要用某种方式铸造它吗?我需要一些其他的Object
作为List<>
吗?任何有帮助的都将不胜感激!
编辑
在RL代码中,我将无法更改DataTemplate部分因为它是XAMLFile
的一部分,将由我的公司创建,所以它将适合这样的参数,但它将仅用于打印。我只将其加载到Find("ItemTemplate")
=>将其转换为DataTemplate
,并使其提供所见即所得对于DataGridCell
,因为宽度和高度将不同于PrintTemplate
到PrintTemplate
解决方案
下面的代码是我的特定问题的解决方案。还可以看看michele Answer
#region example Datacreation
var list = new List<IEnumerable>();
for (int row = 0; row < 5; row++)
{
var myRow = new List<myClass>();
for (int col = 0; col < 5; col++)
{
myRow.Add(new myClass() { ID = col, Name = "Row" + row + " Column:" + col });
}
list.Add(myRow);
}
#endregion
#region FileToDataTemplate
var myXamlFile = "<Window xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' "
+ "xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' "
+ "xmlns:vmv='clr-namespace:toDataGrid;assembly=toDataGrid' " //namespace
+ "SizeToContent='WidthAndHeight'>"
+ "<Window.Resources>"
+ "<DataTemplate x:Name='myFileCellTemplate' DataType='{x:Type vmv:myClass}'>"
+ "<TextBlock Text='{Binding Name}'/>"
+ "</DataTemplate>"
+ "</Window.Resources>"
// some stuff
+ "</Window>";
Window myWindow = (Window)XamlReader.Load(XmlReader.Create(new StringReader(myXamlFile)));
myWindow.Close();
DataTemplate myCellTemplate = (DataTemplate)myWindow.FindName("myFileCellTemplate");
#endregion
DataGrid myDataGrid = new DataGrid();
#region dyn DataGridcreation
for (int col = 0; col < 5; col++)
{
#region HelperDataTemplatecreation
var myResourceDictionaryString = "<ResourceDictionary xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' "
+ "xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' "
+ "xmlns:vmv='clr-namespace:toDataGrid;assembly=toDataGrid'>" //namespace
+ "<DataTemplate DataType='{x:Type vmv:myClass}'>"
+ "<Label Content='{Binding [" + col + "]}'/>"
+ "</DataTemplate>"
+ "</ResourceDictionary> ";
ResourceDictionary ResDic = (ResourceDictionary)XamlReader.Load(XmlReader.Create(new StringReader(myResourceDictionaryString)));
DataTemplate HelpDTemp = (DataTemplate)ResDic[ResDic.Keys.Cast<Object>().First()];
#endregion
DataGridTemplateColumn templateColumn = new DataGridTemplateColumn();
templateColumn.Header = col;
templateColumn.CellTemplate = HelpDTemp;
templateColumn.CellEditingTemplate = HelpDTemp;
myDataGrid.Columns.Add(templateColumn);
}
#endregion
myDataGrid.Resources.Add(new DataTemplateKey(typeof(myClass)), myCellTemplate);
myDataGrid.ItemsSource = list.AsEnumerable<IEnumerable>();
在您的情况下,我将以编程方式生成所有DataGridColumns(如注释中所建议的),这样您就可以为每个单元格分配正确的DataContext,一切都将是动态的。
但是,如果你的问题只是关于DataBinding
问题,那么如果你把TextBlock DataBinding表达式改为:,你的例子就会起作用
<TextBlock Text="{Binding [0].Name}"/>
对于第一个数据模板为[1].Name
,而对于其他两个数据模板则为[2].Name
。这将起作用,因为行DataContext是List<T>
,所以将[#]
添加到DataBinding表达式将把每个单元格的数据上下文设置为正确的对象。
编辑-基于以下评论:如何使用资源中的给定数据模板以编程方式创建数据网格列。
在代码背后
//In your example you have 5 columns
for (int c = 0; c < 5; c++)
{
DataGridTemplateColumn column = new DataGridTemplateColumn();
//Basically i will wrap your DataTemplate in a ContentPresenter
//The ContentProperty is set to point to the correct element of your list
var factory = new FrameworkElementFactory(typeof(ContentPresenter));
factory.SetBinding(ContentPresenter.ContentProperty, new Binding(string.Format("[{0}]", c.ToString())));
factory.SetValue(ContentPresenter.ContentTemplateProperty, this.FindResource("YourTemplateName") as DataTemplate);
column.SetValue(DataGridTemplateColumn.CellTemplateProperty, new DataTemplate { VisualTree = factory });
myDataGrid.Columns.Add(column);
}