1

I am wanting to group news articles by year in a repeater. The format would be:

2010

list of articles

2011

List of Articles

My access layer returns a flat list of news articles, specifically List. Therefore, I am grouping them and binding them to the Repeater as follows:

        events = DAL.GetEvents(); 
        var groupedNewsList = from e in events 
            group e by e.StoryDate.Year 
            into g 
            select new { 
                Year = g.Key
                , Events = g 
            };

        rptEvents.DataSource = groupedNewsList;
        rptEvents.DataBind(); 

The problem is trying to get the List from within the ItemDataBound event. So far, I have the following:

        var data = e.Item.DataItem;

        System.Type type = data.GetType();
        // getting the year works fine
        string year = (string)type.GetProperty("Year").GetValue(data, null).ToString();
        // this returns something, but I can't access any properties. I need to get 
        //access to the contained List<News>
        var newsList = type.GetProperty("Events").GetValue(data, null);

Any ideas?

Thanks in advance!

SchmitzIT
  • 9,227
  • 9
  • 65
  • 92
gilpach
  • 1,367
  • 3
  • 16
  • 34

2 Answers2

3

You don't have a List<News> - you just have a grouping. If you want a List<News>, you'll need to change your query, e.g.

var groupedNewsList = from e in events
                      group e by e.StoryDate.Year into g
                      select new { Year = g.Key, Events = g.ToList() };

Note that if you're using C# 4 you could do reflection rather more easily using dynamic typing:

dynamic data = e.Item.DataItem;
string year = data.Year.ToString();
List<News> newsList = data.Events;

Alternatively, you could avoid using an anonymous type in the first place - create your own GroupedNewsList type with Year and Events properties, populate that in your query, and then cast to it in your event handler.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
1

The "sender" object in the ItemDataBound event is the repeater -- use it to get to the data-source. If the data-source has been grouped before binding, you can compare the current value to the previous value & hide the year-field if they are equal. Like this:

MyObject item = (MyObject)item.DataItem;
Repeater repeater = (sender as Repeater);
List<MyObject> items = repeater.DataSource as List<MyObject>;

Label lblGrouping = (Label)item.FindControl("lblGrouping");
if (item.ItemIndex == 0 || item.DateField.Year != items[item.ItemIndex - 1].DateField.Year) {
    lblGrouping.Text = item.DateField.Year.ToString();
}

This worked for me, as I used a table with each row being one item, and the left-most column contained the "lblGrouping" control.

Jeff Landon
  • 31
  • 1
  • 6