问题描述:

I'm trying to load data to DataGrid from a generic list.

the relevant code:

XAML:

<Grid>

<DataGrid DataContext="{Binding Lines}"

ItemsSource="{Binding}"

AutoGenerateColumns="True">

</DataGrid>

</Grid>

C#:

 public IList<IReportLine> Lines { get; set; }

public interface IReportLine {}

public class ReportLine : IReportLine

{

public string A { get; set; }

public string B { get; set; }

}

It seems that the columns are taken from the type IReportLine - so I'm getting an empty DataGrid.

Of course, if I'm changing IReportLine definition to:

public interface IReportLine

{

string A { get; set; }

string B { get; set; }

}

it works perfectly, but i can't do that because every class that implement IReportLine has different Properties.

What can I do in order to make the columns be generated from the dynamic type of IReportLine?

Or have any other idea to solve my problem?

Thanks!

EDIT:

The interface holding the Lines property and the class implementing the interface(one of many):

 interface IReport

{

string Header { get; set; }

IList<IReportLine> Lines { get; set; }

}

public class Report : IReport

{

public string Header

{

get;

set;

}

public IList<IReportLine> Lines

{

get;

set;

}

}

The DataContext of the DataGrid is IReport object.

So I can't Change

public IList<IReportLine> Lines { get; set; }

to

public IList<ReportLine> Lines { get; set; }

网友答案:

Instead of defining members in interface, make the list to be more verbose. You gotta tell dataGrid at least some specific type so that it can look for properties in it.

Change

public IList<IReportLine> Lines { get; set; }

to

public IList<ReportLine> Lines { get; set; }

UPDATE

Like I mentioned above, if you want columns to be auto generated, you gotta supply some specific type.

Consider scenario where you have another class say AnotherReportLine implementing IReportLine:

public class AnotherReportLine : IReportLine
{
    public string A { get; set; }
    public string B { get; set; }
    public string C { get; set; }
}

Now, you can add both class instances in Lines collection like this:

 Lines = new List<IReportLine>();
 Lines.Add(new ReportLine() { A = "A1", B = "B1" });
 Lines.Add(new AnotherReportLine() { A = "A1", B = "B1", C = "C1" });

What should be the columns list now?

A | B OR A | B | C. WPF engine cannot infer that without your help.

That brings you down to three possible ways:

  • Move properties to interface.
  • Make the list of more specific type.
  • Last set AutoGenerateColumns to False and provide your own list of columns you want to show.
相关阅读:
Top