Reputation: 1546
I have a list box
that has a list of user controls. Each user control has 5 combo boxes. I want to be able to read the selected text of each combo box in each user control from the main application. However, when I change the selection in the combo box, the text property of the combo box in the user control doesn't change when I read it in the main application.
Code-behind:
radQueryParamList.Items.Add(new TCardQueryParameters());
Xaml (This is just a data template for how to display a TCardQueryParameters object):
<DataTemplate x:Key="TCardViewQueryParamDataTemplate">
<tcardqueryparam:TCardQueryParameters x:Name="TCardViewerParamUC" />
</DataTemplate>
<telerik:RadListBox Grid.Column="1" ItemTemplate="{StaticResource TCardViewQueryParamDataTemplate}" Name="radQueryParamList" VerticalAlignment="Top" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Grid.ColumnSpan="3">
Where I loop over the list of user controls
string test = radTESTGACC.Text;//TEST combo box, Text property changes
//radQueryParamList is a listbox of user controls where TCardQueryParameters is the UC
foreach(TCardQueryParameters param in radQueryParamList.Items)
{
//Each UC has a radGACC combo box in it, and I am reading what the user
//selected for each user control here in the main app, but the text property
//never changes
String gacc = param.radGACC.Text; //Text property DOESN'T CHANGE
}
I thought that each instance of the user control would keep its own state and I would just be able to read what the user selected for that combo box, but that doesn't seem to be the case.
Upvotes: 0
Views: 391
Reputation: 132548
You have not bound the SelectedItem
, SelectedValue
, or SelectedIndex
property of your internal ComboBox
to anything so it maintains its selection.
An ItemTemplate
is like a cookie cutter. It contains the definition of the object, but not the object itself. Properties specific to the object's state are lost unless they are bound to something on the DataContext
behind the template.
This is important to note for two aspects.
First off, to improve performance WPF usually unloads items which are not visible, which often results in items being re-created from their template anytime they are reloaded. An example would be when you minimize an application to the taskbar, then maximize it again. This is usually better on performance and memory usage, however it does mean you have to be sure you store the state of items that were created with a Template
somewhere.
And second, by default ListBoxes
use something called virtualization. A simple way of explaining this would be this:
Suppose you have a ListBox of 100,000 items. In your ListBox
, only 10 items can be visible at a time. WPF will render roughly 14 items (the 10 visible ones, and then a few extra for a scroll buffer so you don't see anything unusual while scrolling). When you scroll to new items, WPF just re-uses the existing items that are already rendered, and just replaces the DataContext
behind those items.
As you can guess, it is far better on performance to render 14 UI items instead of 100k items.
So to answer your question, you will probably want to bind either SelectedItem
, SelectedValue
, or SelectedIndex
of your TCardQueryParameters
UserControl to a property on the DataContext
(which in your case appears to be another different UserControl
).
It should probably be noted that what you are essentially doing is creating a list of UserControls
, assigning them to the ListBox
, and then telling the ListBox
that it should draw each UserControl
with another separate UserControl
. So although you are changing the SelectedItem
in the template UserControl
, that change is not being reflected to your ListBox.Items
copy of the UserControl
.
I'm guessing you probably don't want that, so would recommend removing your ItemTemplate
completely.
Or better yet, create a new class object containing all the data for your UserControl
, and adding that to your ListBox.Items
. Then tell the ListBox to draw that item using a TCardQueryParameters
UserControl as the ItemTemplate
, like you have now.
Upvotes: 3