简体   繁体   English

如何添加清单 <List<MyClass> &gt;()作为DataGrid.ItemsSource

[英]how to add List<List<MyClass>>() as DataGrid.ItemsSource

The Problem 问题

if i have such a List let's call it Rows and i wan't to add like myDataGrid.ItemsSource = Rows; 如果我有这样一个列表,就称它为“ Rows而我不想像myDataGrid.ItemsSource = Rows;一样添加myDataGrid.ItemsSource = Rows; than i get in all Columns the first myClass per subList 比我在所有列中获得每个子列表的第一个myClass

it looks like 看起来像

 Column0  |  Column1  |  Column2  |  Column3

firstrow0 | firstrow0 | firstrow0 | firstrow0
firstrow1 | firstrow1 | firstrow1 | firstrow1
firstrow2 | firstrow2 | firstrow2 | firstrow2

The Code 编码

XAML 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<> ? 我是否需要其他一些Object作为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. 在RL代码中,我将无法更改DataTemplate部分,因为它是XAMLFile一部分,该部分将由我公司创建,因此适合参数,但原始参数仅用于打印。 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 我只将其加载到Find("ItemTemplate") =>将其转换为DataTemplate并为DataGridCell提供WYSIWYG,因为从PrintTemplatePrintTemplate的宽度和高度将有所不同

Solution

the following code is the solution for my specific Problem take also a look at michele Answer 以下代码是针对我特定问题的解决方案,也请看看michele答案

        #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. 在您的鞋子中,我将以编程方式生成所有DataGridColumns(如注释中所建议),因此您可以为每个单元格分配正确的DataContext,并且所有内容都将是动态的。

But, if your question it's only about a DataBinding problem, your example will work if you change your TextBlock DataBinding expression to: 但是,如果您的问题仅是有关DataBinding问题的,那么如果将TextBlock DataBinding表达式更改为以下示例,则示例将起作用:

<TextBlock Text="{Binding [0].Name}"/>

for the first data template, [1].Name and [2].Name for the other two DataTemplates. 对于第一个数据模板,对于其他两个数据模板,为[1].Name[2].Name 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. 这将起作用,因为您的行DataContext是List<T> ,因此将[#]添加到DataBinding表达式会将每个单元格的数据上下文设置为正确的对象。

EDIT - Based on comments below: How to create datagridcolumn programmatically using a given datattemplate from resources. 编辑-基于以下注释:如何使用资源中的给定datattemplate以编程方式创建datagridcolumn。

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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM