Click here to Skip to main content
15,886,110 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hi everyone,

I have a connected services and use properties to retrieve data from EF6.
In a testapplication I can create a list with these propertyname to fill a combobox
ConnectedDataServices.DataServiceContext.GetType().GetRuntimeProperties().Select(x => x.Name).ToList();

I can get the vales from he property but as type object instead of the original type ConcurrentBag<>.

But how do I get the contents or values of the object to bind the concurrentbag desired?

What I have tried:

var selectedProp = comboBox1.SelectedItem.ToString();

            PropertyInfo propInfo = _availableProps.FirstOrDefault(x => x.Name == selectedProp);
            var results = propInfo.GetValue(ConnectedDataServices.DataServiceContext, null);
            Type type = results.GetType();
            dataGridView1.DataSource = results;
            dataGridView1.Refresh();

results is now object type instead of ConcurrentBag<entity>
Posted
Updated 26-Jun-18 4:46am
v3
Comments
Richard Deeming 26-Jun-18 9:31am    
The compile-time type of result will be object; but the run-time type will be whatever type the property returns.

The DataSource property takes an object, so I'm struggling to see what the problem is.
Herman<T>.Instance 26-Jun-18 10:30am    
The problem was that I used ConcurrentBag in my WCF. Changing to a List<> object solved the problem. DataGridView cannot show data from ConcurrentBAG<> objects I suppose.
Richard Deeming 26-Jun-18 10:34am    
That sounds about right. The documentation[^] says that the DataSource requires an object that implements either IList, IListSource, IBindingList, or IBindingListView. But ConcurrentBag[^] doesn't implement any of those interfaces.

1 solution

If you're using a recent version of the C# compiler, you can use a pattern-matching switch to make sure the property value is of the correct type:
C#
switch (results)
{
    case null:
    case IList _:
    case IListSource _:
    {
        // Includes IBindingList and IBindingListView
        dataGridView1.DataSource = results;
        break;
    }
    case ICollection collection:
    {
        dataGridView1.DataSource = new ArrayList(collection);
        break;
    }
    case IEnumerable sequence:
    {
        dataGridView1.DataSource = sequence.Cast<object>().ToList();
        break;
    }
    default:
    {
        // Not a supported type:
        dataGridView1.DataSource = null;
        break;
    }
}

It would be simple enough to convert this to work in an older compiler, but it wouldn't be as clean. :)
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900