如何添加列表<名单,LT; MyClass的>>()作为DataGrid.ItemsSource [英] how to add List<List<MyClass>>() as DataGrid.ItemsSource
问题描述
问题
如果我有这样一个名单,让我们把它叫做行
我wan't添加像 myDataGrid.ItemsSource =行;
比我所有列得到每子列表中的第一个myClass的
它看起来像
Column0 | COLUMN1 |列2 |栏3
firstrow0 | firstrow0 | firstrow0 | firstrow0
firstrow1 | firstrow1 | firstrow1 | firstrow1
firstrow2 | firstrow2 | firstrow2 | firstrow2
代码
XAML
< DataGrid的名称=myDataGrid的AutoGenerateColumns =FALSE>
< DataGrid.Columns>
< DataGridTemplateColumn>
< DataGridTemplateColumn.CellTemplate>
<数据类型的DataTemplate ={X:类型VMV:MyClass的}>
< TextBlock的文本={绑定名称}/>
< / DataTemplate中>
< /DataGridTemplateColumn.CellTemplate>
< / DataGridTemplateColumn>
< DataGridTemplateColumn>
< DataGridTemplateColumn.CellTemplate>
<数据类型的DataTemplate ={X:类型VMV:MyClass的}>
< TextBlock的文本={绑定名称}/>
< / DataTemplate中>
< /DataGridTemplateColumn.CellTemplate>
< / DataGridTemplateColumn>
< DataGridTemplateColumn>
< DataGridTemplateColumn.CellTemplate>
<数据类型的DataTemplate ={X:类型VMV:MyClass的}>
< TextBlock的文本={绑定名称}/>
< / DataTemplate中>
< /DataGridTemplateColumn.CellTemplate>
< / DataGridTemplateColumn>
< /DataGrid.Columns>
< / DataGrid的>
背后
VAR名单=新名单<名单,LT; MyClass的>>();
为(INT行= 0;排3;;排++)
{
变种myRow =新的List< MyClass的>();
为(INT COL = 0;西小于5;西++)
myRow.Add(新MyClass的(){ID =关口,名称=行+行+列:+ COL} );
list.Add(myRow);
}
myDataGrid.ItemsSource = list.AsEnumerable<&IEnumerable的GT;();
MyClass的
公共MyClass类
{
公众诠释ID {搞定;组; }
公共字符串名称{;组; }
//其他的东西
}
问题
我需要什么来得到这个工作。我需要投以某种方式?我需要一些其他的对象
为列表与LT;>
?
任何可能帮助是非常感谢!
修改
在RL代码,我也不会能够改变的DataTemplate部分
,因为 XAMLFile
的一部分,将由我公司创建,因此它适合这样的参数,但原来它只会打印。我只加载到查找(ItemTemplate中)
=>强制转换为的DataTemplate
键,我们就提供一个所见即所得
为 DataGridCell
,因为宽度和高度将是 PrintTemplate
不同于 PrintTemplate
解决方案
下面的代码是针对我的具体问题采取的解决方案也看看米歇尔回答
#地区例如Datacreation
无功名单=新名单,LT; IEnumerable的>();
为(INT行= 0;排小于5;排++)
{
变种myRow =新的List< MyClass的>();
为(INT COL = 0;西小于5;西++)
{
myRow.Add(新MyClass的(){ID =关口,名称=行+行+栏目:+ COL});
}
list.Add(myRow);
}
#endregion
#地区FileToDataTemplate
VAR myXamlFile =<窗口的xmlns =HTTP://schemas.microsoft.com/winfx/2006/ XAML /演示'
+的xmlns:X =的http://schemas.microsoft.com/winfx/2006/xaml'
+的xmlns:VMV ='CLR命名空间:toDataGrid;装配= toDataGrid'//命名空间
+SizeToContent ='WidthAndHeight'>中
+< Window.Resources>中
+<的DataTemplate X:名称='myFileCellTemplate'数据类型='{X:类型VMV:MyClass的}'>中
+< TextBlock的文本={绑定名}/>中
+< / DataTemplate中>中
+< /Window.Resources>
//一些东西
+< /窗gt;中;
窗口为mywindow =(窗口)XamlReader.Load(XmlReader.Create(新StringReader(myXamlFile)));
myWindow.Close();
的DataTemplate myCellTemplate =(DataTemplate中)myWindow.FindName(myFileCellTemplate);
#endregion
DataGrid中myDataGrid =新DataGrid中();
#地区DYN DataGridcreation
为(INT COL = 0;西小于5;西++)
{
#地区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命名空间:toDataGrid;装配= toDataGrid'>中//命名空间
+<数据类型的DataTemplate ='{X:类型VMV:MyClass的}'>中
+<标签内容={结合[+ COL +]}/>中
+< / DataTemplate中>中
+< / ResourceDictionary中>中;
的ResourceDictionary ResDic =(ResourceDictionary中)XamlReader.Load(XmlReader.Create(新StringReader(myResourceDictionaryString)));
的DataTemplate HelpDTemp =(DataTemplate中)ResDic [ResDic.Keys.Cast&所述;对象>()第一()];
#endregion
DataGridTemplateColumn TemplateColumn中=新DataGridTemplateColumn();
templateColumn.Header =关口;
templateColumn.CellTemplate = HelpDTemp;
templateColumn.CellEditingTemplate = HelpDTemp;
myDataGrid.Columns.Add(TemplateColumn中);
}
#endregion
myDataGrid.Resources.Add(新DataTemplateKey(typeof运算(MyClass的)),myCellTemplate);
myDataGrid.ItemsSource = list.AsEnumerable<&IEnumerable的GT;();
在你的鞋,我会编程生成所有DataGridColumns(如在评论中所建议的),所以你可以正确的DataContext分配到每一个细胞,一切都将是非常动态的。
但是,如果你的问题是只有一个<$ C
:$ C>数据绑定
的问题,如果你改变你的TextBlock数据绑定表达式的示例将工作< TextBlock的文本={结合[0] .Name点}/>
第一个数据模板, [1] .Name点
和 [2] .Name点
其他两个的DataTemplates。
这是将工作怎么一回事,因为你行的DataContext是一个列表< T>
,所以加入 [#]
来如何创建一个DataGridColumn编程使用给定datattemplate从资源:基于下面的评论 - 您的数据绑定表达式将设置每一个细胞的正确对象的数据上下文
编辑。
在后面的代码
/ /在你的榜样,你有5列
的for(int c = 0; C< 5; C ++)
{
DataGridTemplateColumn列=新DataGridTemplateColumn();
//基本上我将包装你的DataTemplate中//将ContentProperty设置为指向您的列表
变种厂=新FrameworkElementFactory(typeof运算(ContentPresenter))的正确元素ContentPresenter
;
factory.SetBinding(ContentPresenter.ContentProperty,新的Binding(的String.Format([{0}],c.ToString())));
factory.SetValue(ContentPresenter.ContentTemplateProperty,this.FindResource(YourTemplateName)作为DataTemplate中);
column.SetValue(DataGridTemplateColumn.CellTemplateProperty,新的DataTemplate {=的VisualTree工厂});
myDataGrid.Columns.Add(列);
}
The Problem
if i have such a List let's call it Rows
and i wan't to add like myDataGrid.ItemsSource = Rows;
than i get in all Columns the first myClass per subList
it looks like
Column0 | Column1 | Column2 | Column3
firstrow0 | firstrow0 | firstrow0 | firstrow0
firstrow1 | firstrow1 | firstrow1 | firstrow1
firstrow2 | firstrow2 | firstrow2 | firstrow2
The Code
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>
behind
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
}
The Question
What do i need to get this working. Do i need to cast it in some way? Do i need some other Object
as a List<>
?
Anything that could help is greatly appreciated!
EDIT
in RL Code i will not be able to change the DataTemplate part
because it part of XAMLFile
that will created by my company so it will fit so parameters but original it will only be for printing. I only load it to Find("ItemTemplate")
=> cast it as DataTemplate
and us it to provide a WYSIWYG
for the DataGridCell
because the Width and Height will be different from PrintTemplate
to PrintTemplate
Solution
the following code is the solution for my specific Problem take also a look at 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>();
In your shoes I will generate all the DataGridColumns programmatically (as suggested in the comments) so you can assign the correct DataContext to every cell and everything will be really dynamic.
But, if your question it's only about a DataBinding
problem, your example will work if you change your TextBlock DataBinding expression to:
<TextBlock Text="{Binding [0].Name}"/>
for the first data template, [1].Name
and [2].Name
for the other two DataTemplates.
That's will work beacuse your row DataContext is a List<T>
, so adding [#]
to your DataBinding expression will set the data context of every cell to the correct object.
EDIT - Based on comments below: How to create datagridcolumn programmatically using a given datattemplate from resources.
In code behind
//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);
}
这篇关于如何添加列表<名单,LT; MyClass的>>()作为DataGrid.ItemsSource的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!