1

I have a list of StudentViewModel object. I am binding this list with a DataGridView, and the column generatation is set to automatic according to the bound model's properties.

   public async Task LoadGridView()
    {
        Tuple<List<StudentViewModel>, int> result = await App.StudentService.SearchAsync(studentRequestModel);
        dataGridView1.DataSource = null;
        dataGridView1.DataSource = result.Item1;
    }

In the StudentViewModel, I have decorated some of the properties with a custom attribute IsViewable.

[AttributeUsage(AttributeTargets.Property)]
public class IsViewable: Attribute
{
    public bool Value { get; set; }
}

usage:

        [IsViewable(Value = true)]
        public string Name { get; set; }

Idea is, just before binding with the UI Control, I want to filter the list and make a new list of anonymous object so that my grid will be populated with only selected properties.

enter image description here

Note: I don't want to create separate view models specific to Grids. I will refactor it if it creates performance issues.

Foyzul Karim
  • 4,252
  • 5
  • 47
  • 70
  • 2
    There is not a way to dynamically generate an anonymous type since the properties need to be known at compile-time. You could use a dictionary to map names and values or populate an `ExpandoObject` and use `dynamic` to get property-like syntax. Either that or create a new `o` and dynamically copying properties that have that attribute. – D Stanley Dec 06 '16 at 15:34
  • This answer might help: https://stackoverflow.com/a/4938442/1220550 – Peter B Dec 06 '16 at 15:38
  • 1
    If I understand correctly you don't want these properties to be shown by the `DataGridView`. If this is what you want, can't you achieve it by using the attribute `[Browsable(false)]` instead of your custom `IsViewable`? – Matteo Umili Dec 06 '16 at 15:38
  • You could also change the visibility of the GridView columns that correspond to those properties. – D Stanley Dec 06 '16 at 15:45
  • @DStanley please correct me if I am wrong, but are you suggesting to touch the gridview? yes. that may be an option. but suppose if want to build a user control and I have a lot of view models, then I can't do it manually. – Foyzul Karim Dec 06 '16 at 15:49
  • @FoyzulKarim Not me, I'm just suggesting of using substitute the use of `IsViewable` property with `Browsable` property – Matteo Umili Dec 06 '16 at 15:50
  • I am tying to generate a dictionary and then convert it to dynamic/anonymous object and then bind it to the grid. will update here. Thank you all for your suggestions. – Foyzul Karim Dec 06 '16 at 15:53
  • @MatteoUmili I can't use platform specific coding here because I planning to use this framework also in web api and xamarin platforms as well. Please kindly check https://github.com/foyzulkarim/GenericComponents if you have time. Thanks – Foyzul Karim Dec 06 '16 at 15:57
  • @DStanley Solved it. please add your valuable comments please. – Foyzul Karim Dec 06 '16 at 16:37
  • @PeterB Solved it. please add your valuable comments please. – Foyzul Karim Dec 06 '16 at 16:37
  • @MatteoUmili Solved it. please add your valuable comments please. – Foyzul Karim Dec 06 '16 at 16:37

1 Answers1

1

The catch is, I serialized the dynamic list and then deserialized. Then I bind that dynamic list with the datagridview and it worked like a charm.

enter image description here

The whole project can be found here foyzulkarim/GenericComponents

Caller / Usage:

        Type type = typeof(StudentViewModel);
        PropertyInfo[] properties = type.GetProperties();
        var infos = properties.Where(x => x.CustomAttributes.Any(y => y.AttributeType == typeof(IsViewable))).ToList();
        List<StudentViewModel> models = result.Item1;
        List<dynamic> list = models.Select(x => GetValue(x, infos)).ToList();
        string serializeObject = JsonConvert.SerializeObject(list);
        var deserializeObject = JsonConvert.DeserializeObject<List<dynamic>>(serializeObject);
        dataGridView1.DataSource = deserializeObject;

enter image description here

enter image description here

Foyzul Karim
  • 4,252
  • 5
  • 47
  • 70