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

Data Annotations

3 Answers 310 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Maurice
Top achievements
Rank 1
Maurice asked on 06 Feb 2018, 05:57 AM

Is there any way to specify the column type and/or templates/editors for a column when autogenerating columns?

I am currently using the DisplayAttribute and a custom attribute with a behavior to manage column specific things that the DisplayAttribute does not support. If there is no way to support this, I figure I could add a TemplateSelector type to the GridColumnDisplayAttribute for the edit template. If this is the only way are there any links/projects showing how I can achieve this for complex controls and bindings like an autocomplete?

An example of what I am using now:

01.private bool isSelected = true;
02.    [Display(Name = "Selected", Order = 0)]
03.    [GridColumnDisplay(CanHide = false, Width = 25, Resizeable = false, TextAlignment = TextAlignment.Center)]
04.    public bool IsSelected
05.    {
06.      get => isSelected;
07.      set => this.SetValue(ref isSelected, value);
08.    }
09. 
10.    private string name;
11.    [Display(ResourceType = typeof(Resources.Properties.Resources), Name = ResourceKeys.GridHeader_AccountName)]
12.    public string AccountName
13.    {
14.      get => name;
15.      set => this.SetValue(ref name, value);
16.    }

 

1.<telerik:RadGridView ItemsSource="{Binding Accounts}">
2.  <i:Interaction.Behaviors>
3.    <gridBehaviors:GridColumnsBehavior />
4.  </i:Interaction.Behaviors>
5.</telerik:RadGridView>

 

Thanks,
Maurice

3 Answers, 1 is accepted

Sort by
0
Maurice
Top achievements
Rank 1
answered on 06 Feb 2018, 09:25 AM

This is what I came up with, I am interested to know if anyone sees any issues with the implementation. I quite like the idea of driving the column generation automatically and supplementing that with attributes. It makes my use case of multiple grids of varying columns per-user setting easier to manage and test ... I think.

Hopefully, I have not re-invented the wheel here or introduced any memory (or other) issues.

The GridView behavior

01.private void OnAutoGeneratingColum(object sender, GridViewAutoGeneratingColumnEventArgs e)
02.    {
03.      var column = e.Column as GridViewBoundColumnBase;
04.      var property = e.ItemPropertyInfo.Descriptor as PropertyDescriptor;
05.      var attrib = GetColumnAtttribute(e.ItemPropertyInfo.Name, property.ComponentType);
06.
07.      if (attrib != null)
08.      {
09.        column.TextAlignment = attrib.TextAlignment;
10.        column.Width = attrib.Width > 0 ? new GridViewLength(attrib.Width) : GridViewLength.Auto;
11.        column.IsResizable = attrib.Resizeable;
12.
13.        // create the typed column based on the custom attribute
14.        if (attrib.ColumnFactoryType != null)
15.        {
16.          var factory = Activator.CreateInstance(attrib.ColumnFactoryType) as IGridViewColumnFactory;
17.          e.Column = factory.Create(column);
18.        }
19.      }
20.    }

 

The custom attribute usage on the grid data model property

1.private string activity;
2.[Display(ResourceType = typeof(Resources.Properties.Resources), Name = ResourceKeys.GridHeader_Activity)]
3.[GridColumnDisplay(ColumnFactoryType = typeof(ActivityTypeGridViewColumnFactory))]
4.public string Activity
5.{
6.  get => activity;
7.  set => this.SetValue(ref activity, value);
8.}

 

The factory implementation

01.public class ActivityTypeGridViewColumnFactory : IGridViewColumnFactory
02.  {
03.    private BindableCollection<ActivityType> ActivityTypes { get; } = new BindableCollection<ActivityType>();
04.
05.    public GridViewColumn Create(GridViewBoundColumnBase column)
06.    {
07.      if (!ActivityTypes.Any())
08.      {
09.        // todo: remove service locator and populate this collection once only
10.        ActivityTypes.AddRange(IoC.Get<AddPromotionDataProvider>().GetActivityTypes());
11.      }
12.
 
  13.       return new GridViewComboBoxColumn
14.      {
15.        ItemsSource = ActivityTypes,
16.        DisplayMemberPath = nameof(ActivityType.Name),
17.        SelectedValueMemberPath = nameof(ActivityType.Value),
18.        DataMemberBinding = column.DataMemberBinding
19.      };
20.    }
21.  }

 

Many thanks,
Maurice

0
Stefan
Telerik team
answered on 08 Feb 2018, 01:57 PM
Hello Maurice,

Thank you for the update.

Indeed, using the AutoGeneratingColumn event of the control is the recommended mechanism for altering the automatically generated columns. As you have already found, the event arguments expose the Column property which you can set as per your needs. I reviewed the implementation you are using and cannot find any possible issues. You should be able to safely stick to it.

Feel free to update me in case further assistance is needed.

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
Maurice
Top achievements
Rank 1
answered on 08 Feb 2018, 11:18 PM

Hi Stefan,

Thanks for taking a look.

Regards,
Maurice

Tags
GridView
Asked by
Maurice
Top achievements
Rank 1
Answers by
Maurice
Top achievements
Rank 1
Stefan
Telerik team
Share this question
or