如何添加列表<;列表<;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,因为宽度和高度将不同于PrintTemplatePrintTemplate

解决方案

下面的代码是我的特定问题的解决方案。还可以看看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>();

如何添加列表<;列表<;MyClass>>;()作为DataGrid.ItemsSource

在您的情况下,我将以编程方式生成所有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);
}