1

问题

如果我有这样一个列表,让我们调用它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
}

问题

我需要什么才能让这个工作。我需要以某种方式投射它吗?我需要其他ObjectList<>吗?非常感谢任何可以提供帮助的东西!

编辑

在 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>();
4

1 回答 1

1

在您的鞋子中,我将以编程方式生成所有 DataGridColumns(如评论中所建议的那样),因此您可以将正确的 DataContext 分配给每个单元格,并且一切都将是真正动态的。

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

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

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

编辑 - 基于以下评论:如何使用资源中的给定数据模板以编程方式创建 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);
}
于 2013-02-19T15:36:48.663 回答