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

Binding RadGridView with dynamic column.

23 Answers 1840 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Jaspreet
Top achievements
Rank 1
Jaspreet asked on 04 Sep 2015, 05:36 AM

Hi, I am developing a WPF Application using MVVM pattern. I m attaching the final output which is required named "Final output required.jpg" and also what I am currently getting named "GridView xaml.png".

I need to display data in a grid where the columns are dynamic. So in order to achieve that I had created two classes, one named rows and other one columns. Finally I bind the collection containing rows with the GridView. My code sample is as follows:

//Observable property to bind with
        public ObservableCollection<Row> GridRows
        {
            get
            { return _gridRows; }
            set
            {
                _gridRows = value;
                RaisePropertyChanged(() => GridRows);
            }
        }
        //Rad Grid
        public class Grid
        {
            public Grid(){
                Rows = new List<Row>();
            }
 
            //contains mutiple row
            public List<Row> Rows { get; set; }
        }
 
        // RadGrid Row
        public class Row
        {
            public Row()
            {
                Columns = new List<Column>();
            }
 
            // Row Name
            public string RowName { get; set; }
            //each row contains multiple columns
            public List<Column> Columns{ get;set;}
 
        }
 
        //Rad Grid Column
        public class Column {
            public string ColumnName {get;set;}
            public int Value { get; set; }
        }
 
        public void LoadData()
        {
            Grid table = new Grid();
            for (int i = 1; i < 11; i++)
            {
 
                Row row = new Row();
                row.RowName = "Row_" + i;
                for (int j = 0; j < 5; j++)
                {
                    Column Column = new Column
                    {
                        ColumnName = "Row_" + i + "Col_" + j,
                        Value = i + j
                    };
                   
                    row.Columns.Add(Column);
                }
                table.Rows.Add(row);
            }
 
            GridRows = new ObservableCollection<Row>(table.Rows);
        }

 

The View for this is as follows:

<telerik:RadGridView Name="GridView"
                            CanUserReorderColumns="False"
                            CanUserSortColumns="False"
                            ItemsSource="{Binding GridRows}"
                            GridLinesVisibility="Both"
                            AutoGenerateColumns="True"
                             >
           <telerik:RadGridView.Columns >
              
                <!-- My question is how can i bind the dynamic columns here  -->
                <!-- I want to generate the columns spcified for each row -->
               <telerik:GridViewColumn Header = "{Binding Name}" >
                   <telerik:GridViewColumn.CellTemplate>
                       <DataTemplate>
                           <TextBlock Text="{Binding Value}" />
                       </DataTemplate >
                   </telerik:GridViewColumn.CellTemplate>
               </telerik:GridViewColumn >
 
           </telerik:RadGridView.Columns>
       </telerik:RadGridView>

Basically what my requirement is to create dynamic columns as per the Collection of column in Rows. . I tried but it's showing Collection in column.

Also i want to inline editing for columns that why using the GridView. Please check the required output and suggest if there is any other i can use .

Please response soon as i'm in rush .Also let me know if anything not clear.

Thanks

23 Answers, 1 is accepted

Sort by
0
Stefan
Telerik team
answered on 08 Sep 2015, 09:03 AM
Hello Jaspreet,

May I suggest you a slightly different approach for this scenario. It consist of using the ExpandoObject class, as you need to define dynamic columns. Using your current data structure, the ExpandoObject will serve as a proxy class, so that RadGridView can "understand" to what data type it is bound to.

First, you will have to define a property for the ItemsSource of RadGridView of type ObservableCollection<IDictionary<string, object>>.  Each IDictionary would represent a row, where its Key is the name of a given column and its Value is the cell content.

Then you will need to iterate over your data structure and add the needed columns to each ExpandoObject and finally add it to aforementioned ObservableCollection. You can check the code snippet below illustrating a similar implementation
ObservableCollection<IDictionary<string, object>> collection =
    new ObservableCollection<IDictionary<string, object>>();
 
foreach (var row in Grid.DataRows)
{
    var expando = (IDictionary<string, object>)new ExpandoObject();
    
    foreach (var item in row.DataItems)
    {
        if (!expando.ContainsKey(item.Column.ColumnName))
        {
            expando.Add(item.Column.ColumnName, item.Value);
        }
    }
 
    collection.Add(expando);
}

Let me know should you need any further assistance.

Best Regards,
Stefan
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Niels
Top achievements
Rank 1
answered on 20 Jan 2016, 05:57 PM

Hello Stefan,

is there a way to get RadDataFilter properly work with your solution? RadDataFilter only gives me Equal, Is Not Equal, Is Null, Is Not Null filtering options. This is probably due to it not knowing the exact data type of the columns.

Thank you for your help.

Niels

0
Stefan
Telerik team
answered on 22 Jan 2016, 03:14 PM
Hi Niels,

I am afraid that this behavior would be expected. The data engine of RadDataFilter adds its filter operators based on whether a given data type is a string or a numeric type. Note, that the dynamic type in most cases is treated as it has type object. You can take a look at the Using Type dynamic article for more information.

So, in such scenarios only the default filter operators are being added and unfortunately, providing a workaround for this scenario would not be possible.

Feel free to contact us should you have any other questions on our controls.

All the best,
Stefan X1
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Derek
Top achievements
Rank 1
commented on 13 Jul 2021, 07:35 PM

Is there a way to dynamically create a class/object (expando or other) that would allow the rad filter to recognize types?
Dinko
Telerik team
commented on 16 Jul 2021, 09:22 AM

You could consider using CustomTypeDescriptor as suggested in this article. You could extend the approach in the article to add dynamic properties to an object with which the RadGridView will be populated.
Derek
Top achievements
Rank 1
commented on 03 Dec 2021, 11:02 PM

@Dinko, not sure I can tag you, but thank you so much! This worked great, and was easy to implement. 
0
Константин
Top achievements
Rank 1
answered on 11 May 2017, 01:24 PM
Can I bind ColumnGroups and Columns to ViewModel? I want to create multiline grouping header, with structure based on data from ViewModel. How does it better to create this header?
0
Stefan
Telerik team
answered on 16 May 2017, 07:01 AM
Hi Константин,

The Columns and ColumnGroups properties of RadGridView are not dependency properties, thus you would not be able to bind them directly to the view model. Moreover, they do not expose a public setter. So, a possible solution would be to implement an attached behavior and handle the required operations through it.

I hope this helps.

Regards,
Stefan X1
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 allow you to write beautiful native mobile apps using a single shared C# codebase.
0
Константин
Top achievements
Rank 1
answered on 17 May 2017, 02:23 PM

Hi!

I need to customize cells by cells dataContext.

I have dataTempate

    <DataTemplate  x:Key="TelerikValueNullableView">
        <foc:ErrorInfoContentControl Style="{StaticResource ColumnErrorStyle}"
                                     Visibility="{Binding IsDataSeriesEmpty, Converter={StaticResource InverseBooleanToVisibilityConverter}}"
                                     Validation.ErrorTemplate="{StaticResource ErrorInfoControlEntityErrorTemplate}"
                                     ErrorInfoSourcePath="{Binding ValueDouble}">
            <Border BorderThickness="2 0 0 0"
                    Visibility="{Binding Path=IsDataSeriesEmpty, Converter={StaticResource InverseBooleanToVisibilityConverter}}"
                    Style="{StaticResource CellRowViewBorderStyle}">
                <telerik:RadMaskedNumericInput   DataContext="{Binding DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type telerik:GridViewCell}}}"
                                                 Mask="#9.3"
                                                 IsReadOnly="True"
                                                 TextMode="PlainText"
                                                 UpdateValueEvent="LostFocus"
                                                 Validation.ErrorTemplate="{x:Null}"
                                                 Visibility="{Binding IsDataSeriesEmpty, Converter={StaticResource InverseBooleanToVisibilityConverter}}"
                                                 Style="{StaticResource CellRowTextViewStyleTelerik}"
                                                 Value="{Binding ValueDouble}" />
            </Border>
        </foc:ErrorInfoContentControl>
    </DataTemplate>

But this dataContext contain Row DataContext by default, and I cant find Data for concrete cells. To solve this problem I written CellTemplateSelector. This Selector contain specific FIeldName for getting Data for concrete Cell.

public class CellTemplateSelector : System.Windows.Controls.DataTemplateSelector
    {
        private string _field;
        private object _cellDataContext;
        private DataTemplate _template;

        public CellTemplateSelector(string field, DataTemplate template)
        {
            _field = field;
            _template = template;
        }

        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {

            var cell = (container as GridViewCell);
            _cellDataContext = (item as IGetObjectByField).GetObject(_field);
            if (_cellDataContext != null)
            {
                cell.DataContext = _cellDataContext;
                return _template;
            }
            else
                return base.SelectTemplate(item, container);
        }
    }

But if i change DataCOntext in CellTemplateSelector - somting going wrong, and cells work uncorrectly(f.e. dont out from editing mode).

Can you provide another solution for problem of getting DataContext for Cell, not for Row (inside dataTemplate for cell). 

0
Stefan
Telerik team
answered on 22 May 2017, 12:50 PM
Hi Константин,

Generally speaking, RadGridView and its CellTemplateCelector mechanism are not meant to be used in such manner. Also, this seems to differentiate from the topic regarding which this thread was initially opened. Note, that we try to keep our support discussions consistent. With this in mind, I would kindly encourage you to open a new support thread and describe your requirement in it and the need to set the DataContext of the cell in such manner.

Thank you in advance for your cooperation.

Regards,
Stefan X1
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 allow you to write beautiful native mobile apps using a single shared C# codebase.
0
Erick
Top achievements
Rank 1
answered on 23 Nov 2017, 10:49 AM
How would I add a combobox with values to the expando object's value? Or is this not possible and if not what would you propose?
0
Stefan
Telerik team
answered on 28 Nov 2017, 09:44 AM
Hello Erick,

Can you please clarify whether you are using the RadGridView or RadComboBox component? Generally speaking, we do not have examples for ExpandoObject in particular, but we have a demo with DynamicObject implementation for RadGridView. It is demonstrated in the Binding to Dynamic Data topic and in the Binding to DynamicObject SDK Example. It can be reviewed through the SDK Samples Browser. The approach for using an ExpandoObject should be basically the same. Can you please check this out?

Regards,
Stefan
Progress Telerik
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 allow you to write beautiful native mobile apps using a single shared C# codebase.
0
pratibha
Top achievements
Rank 1
answered on 09 Mar 2018, 11:49 AM

Hello Telerik team,

is there any demo code for binding RadGridview with dynamic column?

 

0
pratibha
Top achievements
Rank 1
answered on 10 Mar 2018, 02:00 PM
need demo for radgridview dynamic column binding (WPF, MVVM ).  Thanks in advance.
0
Stefan
Telerik team
answered on 14 Mar 2018, 09:01 AM
Hello Pratibha,

All examples discussed in the previously referred article are following the MVVM paradigm. Can you please take a look at it? Do you meet any specific difficulties with these examples?

Regards,
Stefan
Progress Telerik
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 allow you to write beautiful native mobile apps using a single shared C# codebase.
0
John Tobin
Top achievements
Rank 1
answered on 14 May 2018, 09:26 PM

Hi Stefan,

Please see the codes below. I have modified your code.

It is possible to assign custom object to the field where item.value is.

If possible how a property in custom object is bound to grid.

 

ObservableCollection<IDictionary<string, object>> collection =
    new ObservableCollection<IDictionary<string, object>>();

foreach (var row in Grid.DataRows)
{
    var expando = (IDictionary<string, object>)new ExpandoObject();

    foreach (var item in row.DataItems)
    {

        question q1 = new question() {id = 1, value="A"}
        if (!expando.ContainsKey(item.Column.ColumnName))
        {
            expando.Add(item.Column.ColumnName, q1);
        }
    }

    collection.Add(expando);
}

 

public class question : ViewModelBase

{

 

    public string id {get; set;}

    public string value

    {get;

     set;

}

 

 

}

 

0
Stefan
Telerik team
answered on 17 May 2018, 10:38 AM
Hi John,

I am afraid that such nested binding would not be possible to be defined. The data can be populated and edited, but non of the data operations(such as sorting and filtering, for example) would be able to work as expected.

Regards,
Stefan
Progress Telerik
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 allow you to write beautiful native mobile apps using a single shared C# codebase.
0
Huy
Top achievements
Rank 1
answered on 25 Jun 2018, 07:08 AM

Dear Stefan,

You are right. as you said, we need to do a dynamic binding for un-forecast number of columns. Therefore, some default operations are damaged such sorting in my case. How can we fix it? How can we recover sorting? it is throwing an error from system (mscorlib)

I attached a pic for you to see the stacktrace

 

0
Stefan
Telerik team
answered on 27 Jun 2018, 11:25 AM
Hi Huy,

I can confirm that in case of such nested binding as discussed in my previous post the data operations would not be able to work. From the provided image I assume that the LINQ(on which RadGridView depends for processing its data operation) raises the exception. Although I am not aware of the specific setup you are using, please take a look at the previously referred Binding to Dynamic Data article and examples as the recommended and supported approaches are demonstrated in them.

Regards,
Stefan
Progress Telerik
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 allow you to write beautiful native mobile apps using a single shared C# codebase.
0
Krzysiek
Top achievements
Rank 1
answered on 09 Jan 2019, 05:49 PM

Hi, I was hoping you could point me towards a sample that covers some simple column customization for a dynamically bound grid? Such as hiding a specific column or controlling the column width? If there is no sample can you recommend a way to address that?

Thanks

0
Stefan
Telerik team
answered on 11 Jan 2019, 04:10 PM
Hello Krzysiek,

Manipulating the columns in such manner is irrelevant to whether the bound data source is dynamic or not. You can access and set the needed properties are demonstrated in the Defining Columns and Customizing Columns help articles. Can you please take a look at them?

Regards,
Stefan
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Krzysiek
Top achievements
Rank 1
answered on 11 Jan 2019, 05:44 PM

Thanks Stefan,

I'm fairly new to WPF, only a couple months into it so there's a good chance my questions are not even on the right track but I can't seem to use any of the suggested approaches to customizing my columns.

I am using the BindingToICustomTypeDescriptor_WPF as my learning sample, I don't think I can use annotations  because I don't know the column names or column number at design time. The grid will have some subset of cells always present, like the unique ID of the row,. I also can not use any approach the uses code behind in the xaml.cs file, I have to specify the column customization in either my viewmodel using some kind of attribute metadata, or  in the xaml file.

Using the example from the Demo code in BindingToICustomTypeDescriptor_WPF project,  lets say I want to Hide the Name column, and format the Established column

            MyDataRow row = new MyDataRow();
            row.AddPropertyValue("Name", "Liverpool");
            row.AddPropertyValue("StadiumCapacity", 45362);
            row.AddPropertyValue("Established", new DateTime(1892, 1, 1));
            items.Add(row);

I don't know if I'm correct but I think one approach is to use some kind of template, like in my ex. below, I just haven't hit of a way to make this work.

something quick like this would work for the time being until I get a better grasp of WPF :)

    <Window.Resources>
        <local:MyViewModel x:Key="MyViewModel"/>
        <Style x:Key="GridViewHeaderCellStyle" TargetType="telerik:GridViewHeaderCell">
            <Setter Property="Width" Value="200"/>
        </Style>
        <Style x:Key="GridViewColumnStyle" TargetType="telerik:GridViewColumn">
            <Setter Property="IsVisible" Value="False"/>
        </Style>
    </Window.Resources>
    <Grid DataContext="{StaticResource MyViewModel}">
        <telerik:RadGridView ItemsSource="{Binding Data}" 
                             AutoGenerateColumns="True" 
                             GroupRenderMode="Flat"
                             Margin="5" >
            <telerik:RadGridView.Columns >
                <telerik:GridViewDataColumn Header="ID" 
             DataMemberBinding="{Binding Name}" 
             Style="{StaticResource GridViewColumnStyle}" />
            </telerik:RadGridView.Columns>
        </telerik:RadGridView>
    </Grid>

 

 

Maybe a  better approach would be instead of adding a string to add a custom object that has attributes like isVisible or Width, set on the actual dynamically added object.. that was the sample code I was hoping to find, I looked through the 3 samples on dynamic bindings in the grid (BindingToDynamicObject, BindingToICustomTypeDescriptor, BindingToICustomTypeProvider), but non of these samples involves column styling

 

Thank you again

 

Chris

0
Vladimir Stoyanov
Telerik team
answered on 16 Jan 2019, 12:10 PM
Hello Chris,

Thank you for the provided code snippets.

Please, note that adding styles that target the RadGridView columns such as GridViewColumn is not recommended since the columns are not actually visual elements. 

That said, if the columns are defined in xaml, you can set the IsVisible property directly like so:
<telerik:GridViewDataColumn IsVisible="False" />

If the columns are dynamically generated, and you cannot use the xaml.cs file, you can handle the AutoGeneratingColumn event with a command from your viewmodel with our EventToCommandBehavior. In that event you have access to the dynamically generated columns and you can set their properties such as IsVisible or Width.

Hope you find this helpful.

Regards,
Vladimir Stoyanov
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Suma
Top achievements
Rank 1
answered on 26 Feb 2019, 01:55 PM

Hi Team,

Can please help us to bind checkbox control to columns values(true/false). I have attached screenshot.

I have values in code behind:

var row = new MyDataRow();

 foreach (var row in rows)
                        {
                            var row = new MyDataRow();                          
                            foreach (var user in getUsers)
                            {
                                row[string.Format("User1")] = true;
                                row[string.Format("User2")] = true;
                                row[string.Format("User3")] = false;
                            }
                            data.Add(row);
                        }


0
Suma
Top achievements
Rank 1
answered on 27 Feb 2019, 06:14 AM
Adding attachment
0
Vladimir Stoyanov
Telerik team
answered on 01 Mar 2019, 01:27 PM
Hello Suma,

Thank you for the provided picture.

Please, check out the attached sample project which demonstrates how to achieve the desired requirement. 

Hope you find it helpful.

Regards,
Vladimir Stoyanov
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Tags
GridView
Asked by
Jaspreet
Top achievements
Rank 1
Answers by
Stefan
Telerik team
Niels
Top achievements
Rank 1
Константин
Top achievements
Rank 1
Erick
Top achievements
Rank 1
pratibha
Top achievements
Rank 1
John Tobin
Top achievements
Rank 1
Huy
Top achievements
Rank 1
Krzysiek
Top achievements
Rank 1
Vladimir Stoyanov
Telerik team
Suma
Top achievements
Rank 1
Share this question
or