3

I need to bind WPF DataGrid to an observable list of objects and I need public properties of the objects to determine the columns of the grid. the grid needs to update every time property is changed. I need to generate this grid automatically and dynamically depending on the class in the observable collection, as I do not know what properties the object will have (e.g. inherited classes may add new properties).

I have managed to make such grid: columns are added automatically, new items added to the collection are instantly visible in the grid. however, I do not know how to inform the grid of the change in the properties. I have seen many answers to SIMILAR problems like:

How do I bind a WPF DataGrid to a variable number of columns?

or

How do I dynamically generate columns in a WPF DataGrid?

but none of them was addressing exactly the problem I have.

ok, my code. my grid with item source binding:

<DataGrid Name="connectedClientGrid" CanUserAddRows="False" AutoGenerateColumns="true" CanUserSortColumns="False" ItemsSource="{Binding}" HorizontalAlignment="Left" Margin="10,77,0,0" VerticalAlignment="Top" Height="188" Width="550"/>

in window code it is linked to a observable collection:

public ObservableCollection<ClientController> clientControllers = new ObservableCollection<ClientController>(); 

connectedClientGrid.AutoGeneratingColumn += ColumnNameAttribute.dgPrimaryGrid_AutoGeneratingColumn; 
connectedClientGrid.ItemsSource = clientControllers;`

ColumnNameAttribute allows to create columns out of object properties:

public class ColumnNameAttribute : System.Attribute
{
    public ColumnNameAttribute(string Name) { this.Name = Name; }
    public string Name { get; set; }

    static public void dgPrimaryGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
    {
        var desc = e.PropertyDescriptor as PropertyDescriptor;
        var att = desc.Attributes[typeof(ColumnNameAttribute)] as ColumnNameAttribute;
        if (att != null)
        {
            e.Column.Header = att.Name;
        }
    }
}

it is used in the observed class like this:

public partial class ClientController  
{

//properties observed by the interface as grid columns. Inheriting classes may add more properties that will be monitored automatically
    [ColumnName("ID")] public virtual string id {get; set;}
    [ColumnName("Status")] public string status { get; set; }
    [ColumnName("Last message to client")] public string lastSentMessage { get; set; }
 }

this works very well. the only problem is I do not know how to use sth like INotifyPropertyChanged and PropertyChangedEventHandler IN THIS SPECIFIC CASE to notify the grid that property has been changed. at the moment I do

        var tmp = connectedClientGrid.ItemsSource;
        connectedClientGrid.ItemsSource = null;
        connectedClientGrid.ItemsSource = tmp;

every second to make sure grid is refreshed. this works, but it is ugly and I want to find an elegant solution based on binding. thanks for any help.

0 Answers0