我有一个list box
,其中包含用户控件列表。每个用户控件有5个组合框。我希望能够从主应用程序中读取每个用户控件中每个组合框的选定文本。但是,当我在组合框中更改选择时,当我在主应用程序中读取它时,用户控件中组合框的text属性不会改变。
代码隐藏:
radQueryParamList.Items.Add(new TCardQueryParameters());
Xaml(这只是一个如何显示TCardQueryParameters对象的数据模板):
<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">
我遍布用户控件列表的地方
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
}
我认为用户控件的每个实例都会保持自己的状态,我只能读取用户为该组合框选择的内容,但似乎并非如此。
答案 0 :(得分:3)
您尚未将内部SelectedItem
的{{1}},SelectedValue
或SelectedIndex
属性绑定到任何内容,以便保持其选择。
ComboBox
就像一个千篇一律的人。它包含对象的定义,但不包含对象本身。特定于对象状态的属性将丢失,除非它们绑定到模板后面ItemTemplate
上的某些内容。
这有两个方面需要注意。
首先,为了提高性能,WPF通常会卸载不可见的项目,这通常会导致项目在重新加载时从模板中重新创建。例如,当您将应用程序最小化到任务栏时,然后再次将其最大化。这通常在性能和内存使用方面更好,但它确实意味着您必须确保存储在某处使用DataContext
创建的项目的状态。
第二,默认情况下Template
使用称为虚拟化的东西。一个简单的解释方法是:
假设您有一个包含100,000个项目的ListBox。在ListBoxes
中,一次只能显示10个项目。 WPF将渲染大约14个项目(10个可见的项目,然后为滚动缓冲区添加一些额外项目,因此滚动时看不到任何异常)。滚动到新项目时,WPF只会重新使用已呈现的现有项目,只需替换这些项目后面的ListBox
。
正如您所猜测的那样,渲染14个UI项目而不是100k项目的性能要好得多。
因此,要回答您的问题,您可能希望将DataContext
UserControl的SelectedItem
,SelectedValue
或SelectedIndex
绑定到{{1 (在您的情况下,似乎是另一个不同的TCardQueryParameters
)。
应该注意的是,您实际上在做的是创建一个DataContext
列表,将它们分配给UserControl
,然后告诉UserControls
它应该绘制每个ListBox
{ {1}}与另一个单独的ListBox
。因此,虽然您要更改模板UserControl
中的UserControl
,但该更改未反映在SelectedItem
的{{1}}副本中。
我猜你可能不想那样,所以建议你完全删除UserControl
。
或者更好的是,创建一个包含ListBox.Items
所有数据的新类对象,并将其添加到UserControl
。然后告诉ListBox使用ItemTemplate
UserControl作为UserControl
绘制该项目,就像现在一样。