3
votes

I'm using the WPF toolkit datagrid and in the past have always created entities for the grid to bind to, so for example a Contact Entity with Name, Address etc. On the current app I'm working on the user may select from 50 tables and individually select the fields from the tables to generate a view. Clearly here having an Entity to bind to will not work as the binding source will be dynamic.

Question is what do I do?

Thanks

4

4 Answers

5
votes

I just blogged about how to dynamically create columns for a DataGrid based on a reusable model.

2
votes

The best solution is to use Anonymous Types it works perfectly, see the following proof of concept:

<Window x:Class="MyProject.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:System="clr-namespace:System;assembly=mscorlib" 
    Title="MainWindow"
    Height="136" Width="525"
    Loaded="OnWindowLoaded">
<DataGrid ItemsSource="{Binding}">

</DataGrid>

using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;

namespace MyProject {
    public partial class MainWindow : Window
    {
        public class Employee
        {
            public int Id { get; set; }
            public string Code { get; set; }
            public string Name { get; set; }
            public int Job { get; set; }
            public string Address { get; set; }
        }

        private ObservableCollection<Employee> _empCollection;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void OnWindowLoaded(object sender, RoutedEventArgs e)
        {
            // Generate test data
            _empCollection =
                new ObservableCollection<Employee>
                    {
                        new Employee {Id = 234, Code = "E041", Name = "Employee1", Job = 1, Address = "..."},
                        new Employee {Id = 245, Code = "E701", Name = "Employee2", Job = 3, Address = "..."},
                        new Employee {Id = 728, Code = "E001", Name = "Employee3", Job = 9, Address = "..."},
                        new Employee {Id = 663, Code = "E051", Name = "Employee4", Job = 7, Address = "..."},
                    };

            DataContext =
                (from i in _empCollection
                select new {i.Code, i.Name, i.Address}).ToList();
        }
    }
}
2
votes

One approach would be to create a collection of objects, and give each object a custom TypeDescriptor.

When the grid is auto generating columns, it uses reflection over your class - e.g., Customer, and discovers its properties - e.g., FirstName, Balance, etc.

But that's not entirely true. WPF doesn't do the work itself - it asks a TypeDescriptor. And you can implement your own TypeDescriptor, so you can pretend to have properties that don't actually exist. Or in your case, pretend not to have properties that do exist.

0
votes

You can leave binding source as it is, however you can filter DataGrid's columns based on user's preferences of what he/she needs to hide or see.