0
votes
  • I have Window that has a ListBox
  • ListBox(MyListBox) has a DataTable for its DataContext
  • ListBox's ItemSource is : {Binding}
  • Listbox has a UserControl(MyUserControl) as DataTemplate
  • UserControl has RadioButtons and TextBoxes (At first They're filled with values from DataTable and then user can change them)
  • Window has one Submit Button

What I want to do is, when user clicks the submit button

  • For each ListBox Item, get the values form UserControl's TextBoxes and RadioButtons.

I was using that method for this job :

foreach(var element in MyListBox.Items)
{ 
  var border = MyListBox.ItemContainerGenerator.ContainerFromItem(element)as FrameworkElement;
  MyUserControl currentControl = VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(myBorder,0) as Border,0)as ContentPresenter,0)as MyUserControl;
  //And use currentControl
}

I realised nothing when using 3-5 items in Listbox. But when I used much more items, I saw that "var border" gets "null" after some elements looped in foreach function.

I found the reason here : ListView.ItemContainerGenerator.ContainerFromItem(item) return null after 20 items

So what can I do now? I want to access all items and get their values sitting on user controls.

Thanks

2

2 Answers

0
votes

You should use objects who implement INotifyPropertyChanged and bind an ObservableCollection of it to the ItemSource And then you can get all the list of items.

Here some quick links from MSDN to get more informations How to: Implement Property Change Notification Binding Sources Overview

You should google for some tutorials about this.

0
votes

Zied's post is a solution for this problem. But I did the following for my project:

  • I realised that there's no need to use UserControl as DataTemplate in my project. So I removed ListBox's DataTemplate.
  • I removed MyListBox.DataContext = myDataTable and used this:

    foreach(DataRow dr in myDataTable.Rows)
    {
     MyUserControl muc = new MyUserControl(dr);
     myListBox.Items.Add(muc);
    }
    
  • I took DataRow in my UserControl's constructor and did what I want.
  • And at last I could access my UserControls in ListBox by using :
    foreach(MyUserControl muc in
    myListBox) 
    { 
    //do what you want 
    }
    

Easy huh? :)