databarracks
asked on
How to Get ObservableCollections field or column names using for each C# or VB in WPF
Hi guys,
I am trying to obtain the field names of a dynamic observable collection in a for each loop. The data is created at runtime so a bit trickier to get the property/fieldnames of the collection. I can bind to the field names in my XAML no problem and all works well but I need to get the names of all the fields that have been generated at runtime if possible, because I want to map these fields in an insert statement later in my code.
So I am assuming if I can bind items like below the field name does exist somewhere in the dynamic ObservableCollection:
The current code I have is below which tries to loop through observable collection of which nothing happens:
Thank you for your help in advance
I am trying to obtain the field names of a dynamic observable collection in a for each loop. The data is created at runtime so a bit trickier to get the property/fieldnames of the collection. I can bind to the field names in my XAML no problem and all works well but I need to get the names of all the fields that have been generated at runtime if possible, because I want to map these fields in an insert statement later in my code.
So I am assuming if I can bind items like below the field name does exist somewhere in the dynamic ObservableCollection:
<!--<ListBox Grid.Column="1" Grid.Row="1" Width="400" ItemsSource="{Binding SelectedItems}" Margin="5">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding FirstName}"/>
<TextBlock Text="{Binding LastName}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>-->
The current code I have is below which tries to loop through observable collection of which nothing happens:
Private m_selectedItems As ObservableCollection(Of Object)
Public ReadOnly Property SelectedItems() As ObservableCollection(Of Object)
Get
If m_selectedItems Is Nothing Then
m_selectedItems = New ObservableCollection(Of Object)()
m_selectedItems.Add(MyTestCollection)
End If
Return m_selectedItems
End Get
End Property
Public Sub GetColumnsCollection()
Dim myType As Type = SelectedItems.[GetType]()
Dim props As IList(Of FieldInfo) = New List(Of FieldInfo)(myType.GetFields())
For Each prop As FieldInfo In props
Console.WriteLine(prop.FieldType.Name)
Next
End Sub
Thank you for your help in advance
Or for C# use dynamic's:
Each produces the same output as above.
-saige-
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
namespace EE_Q28964322
{
class Program
{
static readonly dynamic people = (from i in Enumerable.Range(0, 20)
let fName = string.Format("FirstName{0}", i)
let mName = string.Format("MiddleName{0}", i)
let lName = string.Format("LastName{0}", i)
let bDate = DateTime.Now.AddYears(-(9 * i))
select new
{
ID = i,
FirstName = fName,
MiddleName = mName,
LastName = lName,
Birthdate = bDate,
FullName = string.Format("{0} {1}. {2}", fName, mName.First(), lName),
Age = string.Format("{0} years old", bDate.Year - DateTime.Now.Year)
});
static ObservableCollection<dynamic> m_selectedItems;
static ObservableCollection<dynamic> SelectedItems
{
get
{
if (m_selectedItems == null)
{
m_selectedItems = new ObservableCollection<dynamic>();
foreach (var p in people)
m_selectedItems.Add(p);
}
return m_selectedItems;
}
}
static void Main(string[] args)
{
GetColumnsCollection();
Console.ReadLine();
}
static void GetColumnsCollection()
{
if (SelectedItems != null && SelectedItems.Count > 0)
{
foreach (var property in SelectedItems[0].GetType().GetProperties())
Console.WriteLine("Column: {0}; TypeOf: {1}", property.Name, property.GetValue(SelectedItems[0], null).GetType());
}
}
}
}
Alternative GetColumnsCollections:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
namespace EE_Q28964322
{
class Program
{
static readonly dynamic people = (from i in Enumerable.Range(0, 20)
let fName = string.Format("FirstName{0}", i)
let mName = string.Format("MiddleName{0}", i)
let lName = string.Format("LastName{0}", i)
let bDate = DateTime.Now.AddYears(-(9 * i))
select new
{
ID = i,
FirstName = fName,
MiddleName = mName,
LastName = lName,
Birthdate = bDate,
FullName = string.Format("{0} {1}. {2}", fName, mName.First(), lName),
Age = string.Format("{0} years old", bDate.Year - DateTime.Now.Year)
});
static ObservableCollection<dynamic> m_selectedItems;
static ObservableCollection<dynamic> SelectedItems
{
get
{
if (m_selectedItems == null)
{
m_selectedItems = new ObservableCollection<dynamic>();
foreach (var p in people)
m_selectedItems.Add(p);
}
return m_selectedItems;
}
}
static void Main(string[] args)
{
GetColumnsCollection();
Console.ReadLine();
}
static void GetColumnsCollection()
{
if (SelectedItems != null && SelectedItems.Count > 0)
{
foreach (var property in SelectedItems.GetType().GetGenericArguments()[0].GetProperties())
Console.WriteLine("Column: {0}; TypeOf: {1}", property.Name, property.GetValue(SelectedItems[0], null).GetType());
}
}
}
}
Each produces the same output as above.
-saige-
ASKER
Thanks for the response. I still have an issue with all of your suggestions because of the for each inside selecteditems. The data can come from different sources so I cannot determine the class or object name as a user can chance the datasource at runtime based on their selection.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Ahh I see:) That makes sense and my solution is now working as expected. Thank you so much for helping me out on this.........awesome work!!
ASKER
it_saige was absolutely on the ball and would like to thank them for their help. First class help and detailed explanations
Open in new window
Produces the following output -
-saige-