Binding RadGridView with dynamic column.

8 posts, 0 answers
  1. Jaspreet
    Jaspreet avatar
    3 posts
    Member since:
    Sep 2015

    Posted 04 Sep 2015 Link to this post

    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

  2. Stefan X1
    Admin
    Stefan X1 avatar
    754 posts

    Posted 08 Sep 2015 Link to this post

    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
  3. Niels
    Niels avatar
    3 posts
    Member since:
    Dec 2009

    Posted 20 Jan 2016 in reply to Stefan X1 Link to this post

    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

  4. Stefan X1
    Admin
    Stefan X1 avatar
    754 posts

    Posted 22 Jan 2016 Link to this post

    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
  5. Константин
    Константин avatar
    3 posts
    Member since:
    May 2017

    Posted 11 May in reply to Stefan X1 Link to this post

    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?
  6. Stefan X1
    Admin
    Stefan X1 avatar
    754 posts

    Posted 16 May Link to this post

    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.
  7. Константин
    Константин avatar
    3 posts
    Member since:
    May 2017

    Posted 17 May in reply to Stefan X1 Link to this post

    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). 

  8. Stefan X1
    Admin
    Stefan X1 avatar
    754 posts

    Posted 22 May Link to this post

    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.
Back to Top