【问题标题】:how to add List<List<MyClass>>() as DataGrid.ItemsSource如何将 List<List<MyClass>>() 添加为 DataGrid.ItemsSource
【发布时间】:2013-02-19 15:09:04
【问题描述】:

问题

如果我有这样的列表,我们称它为 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>();

我的班级

public class myClass
{
    public int ID { get; set; }
    public string Name { get; set; }
    // other stuff
}

问题

我需要什么才能让这个工作。我需要以某种方式投射它吗?我需要其他一些Object 作为List&lt;&gt; 吗? 非常感谢任何可以提供帮助的东西!

编辑

在 RL 代码中,我将无法更改 DataTemplate 部分 因为它是我公司创建的XAMLFile 的一部分,所以它适合这样的参数,但它是原始的,它只用于打印。我只将它加载到Find("ItemTemplate") => 将其转换为DataTemplate 并使用它来提供所见即所得 对于DataGridCell,因为宽度和高度将从PrintTemplatePrintTemplate 不同

解决方案

下面的代码是我的具体问题的解决方案,也看看米歇尔的答案

        #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>();

【问题讨论】:

标签: c# wpf list xaml datagrid


【解决方案1】:

在您的情况下,我将以编程方式生成所有 DataGridColumns(如 cmets 中所建议的那样),因此您可以将正确的 DataContext 分配给每个单元格,并且所有内容都将是动态的。

但是,如果您的问题只是关于 DataBinding 问题,那么如果您将 TextBlock DataBinding 表达式更改为:

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

对于第一个数据模板,[1].Name[2].Name 对于其他两个数据模板。 这将起作用,因为您的行 DataContext 是 List&lt;T&gt;,因此将 [#] 添加到您的 DataBinding 表达式会将每个单元格的数据上下文设置为正确的对象。

编辑 - 基于以下 cmets:如何使用资源中的给定数据模板以编程方式创建 datagridcolumn。

在代码中

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

【讨论】:

  • 如何在代码中做到这一点?因为myDatagrid 它在我的原始代码中生成的代码中,每个属性绑定到my View
  • 我确信我最近已经这样做了。我会搜索sn-p的代码,我会尽快更新答案。
  • 谢谢,但我只记得我认为我不能那样做,因为我的DataTemplate 是固定的(我从File 加载它)所以我想我不能改变这个而不重建DataTemplate
  • 是从文件中加载的?
  • 也许我可以添加一个DataTemplate 来选择[0],而不是在这个DataTemplate 中我可以从DataTemplate 中添加我的DataTemplate File 你觉得怎么样?
猜你喜欢
  • 2019-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-01
  • 1970-01-01
  • 2015-12-26
  • 2013-09-21
  • 1970-01-01
相关资源
最近更新 更多