7

I have been googling and searching for the answers here, but I still fail to understand a very basic thing - How to convert a DataTable to an Observable Collection?

This is how far I've gotten:

public ObservableCollection<Test> test;

public class Test
{
    public int id_test { get; set; }
    public string name { get; set; }
} 

Main..

 DataTable TestTable = new DataTable();
 TestTable.Columns.Add(new DataColumn("id_test", typeof(int)));
 TestTable.Columns.Add(new DataColumn("name", typeof(string)));
 DS.Tables.Add(TestTable);


var test = new ObservableCollection<Test>();
        foreach(DataRow row in test_table.Rows)
     {
         var obj = new Test()
    {
        id_test = (int)row.ItemArray[0],
        name = (string)row.ItemArray[1]

    };
        test.Add(obj);

I updated the code and it seems to be working.

abatishchev
  • 98,240
  • 88
  • 296
  • 433
boo_boo_bear
  • 189
  • 1
  • 4
  • 14

3 Answers3

6

You don't want to create a new collection for each row in the table, but rather one collection for the entire table (with one object in the collection created for one row in the table):

var test = new ObservableCollection<Test>();
foreach(var row in TestTable.Rows)
{
    var obj = new Test()
    {
        id_test = (int)row["id_test"],
        name = (string)row["name"]
    };
    test.Add(obj);
}
Andy
  • 30,088
  • 6
  • 78
  • 89
  • oh my, silly me you are right. But are you sure that the code above works? There is a huge chance that I have missed something, but 1)problem it doesn't recognize "name" – boo_boo_bear May 26 '13 at 13:46
  • @boo_boo_bear I tried to use the same column and property names as you did in your question - maybe there is a difference between the code in your project and what you originally posted? What exact error are you getting? – Andy May 26 '13 at 17:03
  • Thank you for your help. I updated the code in the question, it's working. I know I shouldn't be asking other questions in comment section, but I have no idea how to bind it properly. It doesn't add anything to the ComboBoxColumn – boo_boo_bear May 26 '13 at 18:45
  • @boo_boo_bear yw :) You can always ask another question if you are encountering another problem. – Andy May 26 '13 at 18:48
  • 1
    The semicolon after after the first variable assignment in new Test() needs to be a comma, and the semicolon after the second variable assignment needs to be removed. – lentz Mar 29 '18 at 15:26
2

I had a little issue with the accepted solution. It does not allow the [] brackets on type var.

var test = new ObservableCollection<Test>();
foreach(DataRow row in TestTable.Rows)
{
    test.Add(new Test()
    {
        id_test = (int)row["id_test"],
        name = (string)row["name"],
     });
 }
Patrick Cairns
  • 143
  • 1
  • 7
0

If you intend to use this ObservableCollection to bind to a WPF control and get change notifications then it may be unnecessary to make the DataTable > ObservableCollection conversion. Some built-in WPF controls such as System.Windows.Controls.DataGrid already provides change notification mechanism when bound to a DataTable. For instance, when you add, update or delete rows in the source DataTable, the DataGrid will reflect these changes automatically. Example:

<DataGrid ItemsSource="{Binding ViewModelPropertyAsDataTable}"/>

Some third party controls like Telerik RadGridView, on the other hand, use the DataTable.DefaultView property to provide change notifications. Example:

<telerik:RadGridView ItemsSource="{Binding ViewModelPropertyAsDataTable.DefaultView}"/>
Mustafa Özçetin
  • 1,893
  • 1
  • 14
  • 16