This is a migrated thread and some comments may be shown as answers.

Grid columns from collection

13 Answers 667 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Erik
Top achievements
Rank 1
Erik asked on 13 May 2009, 10:20 PM
I am currently evaluating the GridView control for a project, great product by the way, and have a question on how I can go about implementing the following:

I need to display (in a grid) an employee record with a collection of hours by month, the issue is that the number of months we will be displaying can vary so I cannot use a static template.

EmployeeRecord
    EmployeeName
    ID
    Collection of Hours by month


should be displayed in the grid in the following way:
_________________________________________________________________
ID | EmployeeName | HoursMonth1 | HoursMonth2 | HoursMonth3 | HoursMonth4|...
---------------------------------------------------------------------------------------------------------

Is there a way to do this using the RadControl GridView, add additional columns to the grid for each item in the hours by month collection?

Thanks!

13 Answers, 1 is accepted

Sort by
0
Accepted
Rossen Hristov
Telerik team
answered on 14 May 2009, 01:21 PM
Hello Erik,

You can achieve this. What you need to do is create columns at runtime based on your business scenario. The DataMemberBinding property of each column can be set to point to a list indexer, which in your case will be the hours per month list. Anyway, a code snippet is worth more than a thousand words:

Here is our business object:
using System.Collections.Generic; 
 
namespace Ticket212220_CreateGridColumnsOnTheFly 
    public class EmployeeRecord 
    { 
        public string EmployeeName 
        { 
            get
            set
        } 
 
        public int ID 
        { 
            get
            set
        } 
 
        List<int> hoursByMonth = new List<int>(); 
        public IList<int> HoursByMonth 
        { 
            get { return this.hoursByMonth; } 
        } 
    } 
 

Now, not much of a XAML needed for this:
<Window x:Class="Ticket212220_CreateGridColumnsOnTheFly.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" 
    Title="Window1" Height="300" Width="300"
    <Grid> 
        <telerik:RadGridView Name="grid" AutoGenerateColumns="False"/> 
    </Grid> 
</Window> 
 

And finally, here is how to create columns at runtime and specify their DataMemberBinding:
using System.Collections.Generic; 
using System.Linq; 
using System.Windows; 
using System.Windows.Data; 
using Telerik.Windows.Controls; 
 
namespace Ticket212220_CreateGridColumnsOnTheFly 
    /// <summary> 
    /// Interaction logic for Window1.xaml 
    /// </summary> 
    public partial class Window1 : Window 
    { 
        public Window1() 
        { 
            InitializeComponent(); 
 
            // Get some mock data 
            ICollection <EmployeeRecord> employeeRecords = GetDummyData(); 
 
            //Add the known columns 
            this.grid.Columns.Add(new GridViewDataColumn()  
            {  
                UniqueName = "EmployeeName" 
                , DataMemberBinding = new Binding("EmployeeName"
            }); 
 
            this.grid.Columns.Add(new GridViewDataColumn() 
            { 
                UniqueName = "ID" 
                , DataMemberBinding = new Binding("ID"
            }); 
 
             
            // Now add the dynamic number of columns 
             
            // Determines the maximum number of months that any employee has worked. 
            int maxNumberOfMonths = employeeRecords.Max((x) => x.HoursByMonth.Count); 
            for (int i = 0; i < maxNumberOfMonths; i++) 
            { 
                this.grid.Columns.Add(new GridViewDataColumn() 
                { 
                    UniqueName = "Month" + (i + 1) 
                    , DataMemberBinding = new Binding("HoursByMonth[" + i + "]"
                }); 
            } 
             
            // Finally, bind the grid 
            this.grid.ItemsSource = employeeRecords; 
        } 
 
        static ICollection<EmployeeRecord> GetDummyData() 
        { 
            ICollection<EmployeeRecord> employeeRecords = new List<EmployeeRecord>(); 
 
            EmployeeRecord stevie = new EmployeeRecord() { EmployeeName = "Steven Gerrard", ID = 333 }; 
            stevie.HoursByMonth.Add(1000); 
            stevie.HoursByMonth.Add(2000); 
            stevie.HoursByMonth.Add(3000); 
            stevie.HoursByMonth.Add(4000); 
            employeeRecords.Add(stevie); 
 
            EmployeeRecord ryan = new EmployeeRecord() { EmployeeName = "Ryan Giggs", ID = 222 }; 
            ryan.HoursByMonth.Add(100); 
            ryan.HoursByMonth.Add(200); 
            employeeRecords.Add(ryan); 
 
            EmployeeRecord john = new EmployeeRecord() { EmployeeName = "John Terry", ID = 111 }; 
            john.HoursByMonth.Add(10); 
            john.HoursByMonth.Add(20); 
            john.HoursByMonth.Add(30); 
            employeeRecords.Add(john); 
 
            return employeeRecords; 
        } 
    } 
 

I have attached my small sample project. It should get you started. Please do not hesitate to drop us a line if you have any other questions.

Kind regards,
Ross
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Erik
Top achievements
Rank 1
answered on 14 May 2009, 04:08 PM
Thanks Ross, this works great!
0
Erik
Top achievements
Rank 1
answered on 18 May 2009, 09:55 PM
Hello again Ross,

When I try to edit, by double-clicking the cell, the numeric values in the Grid (in your sample project) I get a null exception, I've tried several things to try to fix this but I cannot find the right combination.

Here is the top of the stack trace:

System.NullReferenceException was unhandled<BR>&nbsp; Message="Object reference   
not set to an instance of an object."<BR>&nbsp;   
Source="Telerik.Windows.Controls.GridView"<BR>&nbsp;   
StackTrace:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at   
Telerik.Windows.Controls.GridView.GridViewCell.ShowEditor() in   
c:\Builds\WPF_Scrum\X1_Q1_2009\Sources\Development\WPF\GridView\GridView\Cells\GridViewCell.cs:line   
488 


Thanks!
0
Rossen Hristov
Telerik team
answered on 19 May 2009, 01:49 PM
Hello Erik,

You will need to specify the data type of the "additional" columns:

            for (int i = 0; i < maxNumberOfMonths; i++) 
            { 
                this.grid.Columns.Add(new GridViewDataColumn() 
                { 
                    UniqueName = "Month" + (i + 1) 
                    , DataMemberBinding = new Binding("HoursByMonth[" + i + "]"
                    , DataType = typeof(int
                }); 
            } 
 

This should solve the problem. If that is not the case, please drop us a line.

Greetings,
Ross
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Timothy Lin
Top achievements
Rank 1
answered on 03 Nov 2009, 07:17 AM
Hi,

I have followed the above code and it works great however I just have one issue where I can't edit the dynamically generated columns! I've tried using both a List and BindingList for my dynamic columns, however when I click on these columns in the grid, it gives me a box to edit but I can't type anything in. I'm not entirely sure what the problem is but I've tried to set the AllowEdit boolean to true on the List which still does not work. Could anyone help with this please? Thank you!

Regards,

Tim.
0
Rossen Hristov
Telerik team
answered on 03 Nov 2009, 08:34 AM
Hello Timothy Lin,

Could you please open a support ticket and send us your project. We will take a look and see where the problem is. Thanks in advance.

Greetings,
Ross
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Timothy Lin
Top achievements
Rank 1
answered on 04 Nov 2009, 05:18 AM
Hi Ross,

Thank you for your prompt reply!

I managed to implement it by setting the GridViewDataColumn's EditorSettings property to a TextBoxEditorSettings object which also supports two-way databinding!

Cheers,

Tim.
0
Jaypee
Top achievements
Rank 1
answered on 03 Sep 2013, 07:48 AM
how to do this in view model? 

for example i have a list of column names in my view model. i bind this list to itemsource. i want to generate the columns dynamically.
0
Dimitrina
Telerik team
answered on 06 Sep 2013, 06:58 AM
Hello,

You can check our online documentation for a further reference on populating data for RadGridView. 

Regards,
Didie
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Yaron
Top achievements
Rank 1
answered on 08 Sep 2013, 07:53 PM
Dear Team.

I'm evaluating your controls library for WPF project and interesting in making this solution with MVVM.
Could you please provide with an example of implementing the original request of this post without using code behind(XAML + ViewModel)?

Thanks in advance.
Yaron
0
Rossen Hristov
Telerik team
answered on 09 Sep 2013, 06:39 AM
Hi,

I am afraid that some things can only be achieved by using actual code. Creating dynamic columns programmatically at runtime is one of them. The MVVM pattern does not exclude using code completely. You can always put the code in an attached behavior and then control this behavior from XAML.

Regards,
Rossen Hristov
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Volodymyr
Top achievements
Rank 1
answered on 30 Mar 2017, 01:34 PM

Hello Rossen ,

 

I'm trying to achieve similar behavior but with a little bit more complex case.

 

What if instead List<int> I have List<Subject> where Subject is:

public class Subject{
 
public string Name{get;set;}
 
publict int Mark{get;set;}
 
}

 

 

And I try to display it in CellTemplate

 

<DataTemplate x:Key="SubjectTemplate">
      <Grid>
          <Grid.ColumnDefinitions>
              <ColumnDefinition Width="Auto"/>
              <ColumnDefinition Width="*"/>
          </Grid.ColumnDefinitions>
          <Grid.RowDefinitions>
              <RowDefinition Height="Auto"/>
              <RowDefinition Height="Auto"/>
              <RowDefinition Height="Auto"/>
          </Grid.RowDefinitions>
 
          <TextBlock Grid.Row="0" Grid.Column="0" Text="Subject"/>
          <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Name}"/>
 
          <TextBlock Grid.Row="1" Grid.Column="0" Text="Mark"/>
          <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Mark}"/>
 
      </Grid>
  </DataTemplate>

 

I'm adding columns in following way

for (int i = 0; i < maxNumberOfMonths; i++)
            {
                this.grid.Columns.Add(new GridViewDataColumn()
                {
                    UniqueName = "Subject" + (i + 1) ,
                    DataMemberBinding = new Binding("Subjects[" + i + "]"),
                    CellTemplate = this.Resources["SubjectTemplate"] as DataTemplate,
                    DataType = typeof(Subject)
                });
            }

 

But for some reason I can't see values of "Name" and "Mark"

0
Stefan Nenchev
Telerik team
answered on 04 Apr 2017, 12:18 PM
Hi Volodymyr,

When you add a CellTemplate to the GridViewDataColumn you should have in mind that the DataContext of the cell is the actual item(in the case of this sample the EmployeeRecord). With this in mind, the binding you have applied would not work. A possible approach is to use MultiValueConverters where you can pass the DataContext and the number of the inner object you need. Please have a look at the modified sample that I have attached for more reference.

Regards,
Stefan Nenchev
Telerik by Progress
Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which you to write beautiful native mobile apps using a single shared C# codebase.
Tags
GridView
Asked by
Erik
Top achievements
Rank 1
Answers by
Rossen Hristov
Telerik team
Erik
Top achievements
Rank 1
Timothy Lin
Top achievements
Rank 1
Jaypee
Top achievements
Rank 1
Dimitrina
Telerik team
Yaron
Top achievements
Rank 1
Volodymyr
Top achievements
Rank 1
Stefan Nenchev
Telerik team
Share this question
or