3

I would like convert DataTable in ObservableCollection without having a specific class in my solution. (All others solution in stackoverflow.com is with specific class.)

The reason is that the DataTable represent a Stored Procedure Result, and in the future I would like change the Stored Procedure result without any change in the application.

I can't bind directly my DataBale because I use Filter on my ModelView side, and I have an exception if I use DataTable and Filter together.

Any idea ?

Thanks

The goal îs to have the same code, but without BO.Line object.

    static public ObservableCollection<BO.Line> GetValues()
    {

        DataTable _dataTable = DAL.ExecuteStoredProcedure(GetStoredProcedureNameInAppConfig());

        ObservableCollection<BO.Line> _list = new ObservableCollection<BO.Line>();

        foreach (DataRow _dataRow in _dataTable.Rows)
        {
            _list.Add(new BO.Line() { Instrument = _dataRow["Instrument"].ToString(), 
                                      Crystal = _dataRow["Crystal"].ToString() });
        }

        return _list;
    }

In this sample:

GetStoredProcedureNameInAppConfig() //return "GetLines"

but i would like change in my App.config (without recompile my application):

GetStoredProcedureNameInAppConfig() //return "GetPerson"

"GetLines" Stored Procedue return:

Instrument | Crystal
______________________
Instr1     | Crystal1
Instr1     | Crystal2
Instr2     | Crystal1

"GetPerson" Stored Procedue return:

FirstName | LastName | Language
_______________________________
Alex      | Doe      | ENG
Britt     | Nillis   | ENG
Carlo     | Petro    | FR

Resume
I would like convert DataTable (with variable structure) in "generic" ObservableCollection. Witout specific class.
(ObservableCollection isn't good solution for me.)

Thank you

OetVV
  • 81
  • 1
  • 4
  • Please post your code so we can see what you actually have done so far. – Osman Esen Dec 16 '14 at 00:36
  • @mattm : Isn't duplicate. In the solution proposed, that I had already read, the specific class "Test" must be created. – OetVV Dec 16 '14 at 08:49
  • You can use `dynamic` instead of a specific type. This does make this question a duplicate of all the others as the only thing you need to change is the type of the collection. This will make your code harder to maintain though, as you'll have to remember the property types each time you try to use the collection. Creating a concrete class takes less than a minute, especially using tools Resharper, but will save you hours of code maintenance – Panagiotis Kanavos Dec 16 '14 at 08:51
  • @PanagiotisKanavos Please show me. – OetVV Dec 16 '14 at 09:20
  • What are you asking? Just use `ObservableCollection` instead of `ObservableCollection` in any of the solutions you've found so far – Panagiotis Kanavos Dec 16 '14 at 09:34
  • 1
    Thank you. ObservableCollection is a good idea, but after I use DataBinding and Reflection on the list. And DataBinding on ObservableCollection isn't possible. – OetVV Dec 16 '14 at 11:07

1 Answers1

2

This solution work with WPF Binding and Filter.

Thank you to http://paulstovell.com/

public class GenericObject
{

    private readonly ObservableCollection<GenericProperty> properties = new ObservableCollection<GenericProperty>();

    public GenericObject(params GenericProperty[] properties)
    {
        foreach (var property in properties)
            Properties.Add(property);
    }

    public ObservableCollection<GenericProperty> Properties
    {
        get { return properties; }
    }

}

public class GenericProperty : INotifyPropertyChanged
{
    public GenericProperty(string name, object value)
    {
        Name = name;
        Value = value;
    }

    public string Name { get; private set; }
    public object Value { get; set; }


    public event PropertyChangedEventHandler PropertyChanged;
}

private static ObservableCollection<GenericObject> Convert(DataTable toConvert)
{
    ObservableCollection<GenericObject> _result = new ObservableCollection<GenericObject>();

    foreach (DataRow _row in toConvert.Rows)
    {
        GenericObject _genericObject = new GenericObject();
        foreach (DataColumn _column in toConvert.Columns)
        {
            _genericObject.Properties.Add(new GenericProperty(_column.ColumnName,_row[_column]));
        }
        _result.Add(_genericObject);
    }

    return _result;
}

Thank you all for your help.

OetVV
  • 81
  • 1
  • 4
  • I get this error - This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread. – Cherylaksh Jun 27 '20 at 07:13