1
votes

Is there a way to determine the associated ObservableCollection programmatically from a ListBox?

I bound the ItemsSource to a ListBox in my XAML and when a user selects an item from within it, I want the program to find not only which ListBox the item came from (which I've managed to do) but also get the ObservableCollection associated with it.

I thought that by using sourceContainer.ItemsSource.ToString() (where sourceContainer is the programmatically-found ListBox) I would be able to determine the DataBound ObservableCollection behind it. However, this isn't the case. What am I missing?

Thanks!

Edit: Here's some code pertaining to the creation of the ObservableCollections and how I'm determining which box is selected. (I know it probably isn't the best way, I'm still learning...)

First off, the XAML (each ListBox has this line for general binding):

ItemsSource="{Binding Path=ListOneItems}"

Now the code for creating the ObservableCollections:

    private ObservableCollection<DataItem> listOneItems;

    public ObservableCollection<DataItem> ListOneItems
    {
        get
        {
            if (listOneItems == null)
            {
                listOneItems = new ObservableCollection<DataItem>();
            }
            return listOneItems;
        }
    }

Here's where the program determines the parent of the selected item:

//Finds the name of the container that holds the selected SLBI (similar to finding the initial touched object)
FrameworkElement determineSource = e.OriginalSource as FrameworkElement;
SurfaceListBox sourceContainer = null;

while (sourceContainer == null && determineSource != null)
{
    if ((sourceContainer = determineSource as SurfaceListBox) == null)
    {
        determineSource = VisualTreeHelper.GetParent(determineSource) as FrameworkElement;
    }
}

//Name of the parent container
strParentContainer = sourceContainer.Name;

//Name of the ObservableCollection associated with parent container?

If anything else is needed, let me know.

3
suppose you don't quite understand what do you need. if you are subscribed to listbox selection changed, you can get the listbox from sender object. var listbox=(ListBox)sender; and than get listbox.ItemsSource to get associated collection - Artiom

3 Answers

2
votes

If you've bound directly to a property that is an ObservableCollection<T>, you should be able to do this:

var col = (ObservableCollection<MyClass>)sourceContainer.ItemsSource;

If that's not the case, you'll need to post the relevant XAML and code.

1
votes

Eren's answer is correct, you can get the actual collection by casting the ItemsSource property to the correct collection type.

ObservableCollection<DataItem> sourceCollection = 
    sourceContainer.ItemsSource as ObservableCollection<DataItem>;

If you only want the Name property as you suggested in the comment, you can get the Binding for the ItemsSourceProperty and look at the Path property

var binding = soureContainer.GetBindingExpression(ListBox.ItemsSourceProperty);
var sourceCollectionName = binding.ParentBinding.Path.Path;
0
votes

The collection you associate with listbox is ObservableCollection? Cuz if you set an array - it doesn't make magic convertion to ObservableCollection in background.

Tell what for do you need this logic. Suppose smth is wrong in other logic.