Problem trying to hide a column when binding RadDataGrid to a DataTable

1 Answer 170 Views
DataGrid
Christopher
Top achievements
Rank 2
Iron
Iron
Christopher asked on 02 May 2022, 06:20 PM

I'm binding a RadDataGrid to a DataTable and it works well, except:

  • I want to hide a few of the columns from the grid without removing them from the DataTable
  • The BindingContextChanged event fires before the columns are created, so I cannot iterate the columns there and hide the ones I don't want to see
  • The DataBindingComplete event never fires at all (at least when binding to the DataTable). It also doesn't fire when the table is Grouped, Sorted, or Filtered although the documentation says it will
  • It also doesn't seem to fire the DataBindingComplete even if the AutoGenerateColumns is set to False (although, as expected, there are no columns displayed at all in this case)

So, basically, I don't see a way to do something after the binding is complete and the columns have been autogenerated.

1 Answer, 1 is accepted

Sort by
1
Accepted
Yana
Telerik team
answered on 05 May 2022, 08:44 AM

Hi Christopher,

Thank you for explaining the situation in details.

I would suggest you use the GenerateColumn Command of the DataGrid as it is fired every time a column is created.  In the command Execute method you can call the default implementation for generating the column only for certain items from the DataTable source. 

Here is a sample GenerateColumn Command implementation:

public class GenerateColumnUserCommand : DataGridCommand
{
    public GenerateColumnUserCommand()
    {
        Id = DataGridCommandId.GenerateColumn;
    }
    public override bool CanExecute(object parameter)
    {
        return true;
    }
    public override void Execute(object parameter)
    {
        var columnPropery = (parameter as GenerateColumnContext).PropertyName;
        if (columnPropery != "Id" && columnPropery != "IsVisited")
        {
            this.Owner.CommandService.ExecuteDefaultCommand(DataGridCommandId.GenerateColumn, parameter);
        }
    }
}

Then just add thus created GenerateColumnUserCommand  command to the DataGrid instance Commands collection:

this.dataGrid.Commands.Add(new GenerateColumnUserCommand());

this.dataGrid.Commands.Add(new GenerateColumnUserCommand());

Please check DataGrid: Commands topic for more information on the provided commands.

As a side note, can you let me know whether you've read about DataBindingComplete event as I am not able to find any information?

Thank you for your feedback.

Regards,
Yana
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Christopher
Top achievements
Rank 2
Iron
Iron
commented on 05 May 2022, 02:30 PM

Thanks, I'm about to implement this to give it a try.

Here's what I read about DataBindingComplete:
https://docs.telerik.com/devtools/xamarin/api/telerik.xamarinforms.datagrid.raddatagrid#Telerik_XamarinForms_DataGrid_RadDataGrid_DataBindingComplete

"Occurs when the associated data (ItemsSource) has been successfully bound to the control or any data operation like Group, Sort or Filter is applied. This event is useful if an additional action is required once the data is ready to be visualized."

This is NOT firing when Group, Sort, or Filter is used, nor does it fire when applying a DataBinding. But that may need to be a different issue/discussion.

Christopher
Top achievements
Rank 2
Iron
Iron
commented on 05 May 2022, 02:50 PM

Worked great, thanks! 

Now to see if I can figure out when Group, Sort, or Filter is being set...

Yana
Telerik team
commented on 09 May 2022, 01:51 PM

Hi Christopher,

Thank you for the follow-up.  Definitely DataBindingComplete event does not behave properly and we're going to investigate this further.

As to the the other question - there are also ApplyGrouping and ApplyFilter commands you can use in a similar way. Still, can you elaborate a little bit more on the scenario related to these actions?

Christopher
Top achievements
Rank 2
Iron
Iron
commented on 10 May 2022, 02:22 PM | edited

This scenario was just trying to figure out a way to not AutoGenerate some columns when binding to a DataTable. Specifically, we have extended attributes on the DataTable's columns that the RadDataGrid doesn't know about and based on the value of those attributes, we don't want to create a column in some cases, but we want the data in those columns to remain in the DataTable. So a slightly modified version of your example for the GenerateColumn Command worked - I actually pass it a list of columns ToHide and as each column is being created, if that column is in ToHide, I just return instead of calling ExecuteDefaultCommand.

I'm also using the ApplyFilter Command now to make the default text filter (the one that creates the composite FilterDescriptor) be case insensitive.

My confusion on the ApplyFilter (and presumably, ApplyGrouping) was that I expected the parameters passed into them to have the references I needed, but they were null. I didn't realize that I needed to call the ExecuteDefaultCommand first and then I could access the FilterDescriptors property on the RadDataGrid and modify the properties I needed to before the actual filtering takes place.

See this other forum post.

Christopher
Top achievements
Rank 2
Iron
Iron
commented on 10 May 2022, 02:24 PM


    public class GenerateColumnUserCommand : DataGridCommand
    {
        private Collection<DataColumn> ToHide { get; set; }
        
        public GenerateColumnUserCommand(Collection<DataColumn> columns)
        {
            Id = DataGridCommandId.GenerateColumn;
            ToHide = columns;
        }
        
        public override bool CanExecute(object parameter)
        {
            return true;
        }

        /// <summary>
        /// If the column needs to be invisible, this skips the default Command, effectively hiding the column
        /// otherwise it calls the base method
        /// </summary>
        /// <param name="parameter"></param>
        public override void Execute(object parameter)
        {
            var columnName = (parameter as GenerateColumnContext)?.PropertyName;

            if (parameter is GenerateColumnContext)
            {
                foreach (var col in ToHide)
                {
                    if (col.ColumnName == columnName)
                    {
                        return;
                    }
                }

                this.Owner.CommandService.ExecuteDefaultCommand(DataGridCommandId.GenerateColumn, parameter);
            }
        }
    }

Tags
DataGrid
Asked by
Christopher
Top achievements
Rank 2
Iron
Iron
Answers by
Yana
Telerik team
Share this question
or