不一致的Silverlight 4 ComboBox下拉显示

我有一个Silverlight 4应用程序,在窗体底部附近有一个ComboBox。 Dropdown中可以有大约30到100个项目。

当我第一次打开ComboBox时,没有SelectedItem,Dropdown向上打开,它可以显示大约23个条目; 只要我没有选择项目,每次重新打开Dropdown时它都会继续这种行为。 一旦我选择了一个项目,每次我打开ComboBox后,它总是向下打开Dropdown,并且只显示3个条目。

我猜Dropdown仅限于3项,因为这是我在屏幕上最大化时窗口的下限。

即使先前已选择某个项目,如何让它显示更多项目?

下面是一个示例Silverlight应用程序,它演示了浏览器内外的行为。

MainPage.xaml中:

                                                        

MainPage.xaml.cs中:

 using System; using System.Windows; using System.Windows.Controls; namespace ComboBox_Test { public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); } private void UpdateDataText(DataTypeDesc oData) { txtData.Text = String.Format("{0}\n\t{1}", oData.Name, oData.Desc); } private void MainPage_OnLoaded(object sender, RoutedEventArgs e) { object[] aDataTypeDescs = new object[] { new DataTypeDesc() {Name = "Boolean", Desc = "A Boolean value"} , new DataTypeDesc() {Name = "Byte", Desc = "An 8-bit unsigned integer"} , new DataTypeDesc() {Name = "Char", Desc = "A Unicode character"} , new DataTypeDesc() {Name = "Double", Desc = "A double-precision floating-point number"} , new DataTypeDesc() {Name = "float", Desc = "A single-precision floating-point number"} , new DataTypeDesc() {Name = "Int16", Desc = "A 16-bit signed integer"} , new DataTypeDesc() {Name = "Int32", Desc = "A 32-bit signed integer"} , new DataTypeDesc() {Name = "Int64", Desc = "A 64-bit signed integer"} , new DataTypeDesc() {Name = "SByte", Desc = "An 8-bit signed integer"} , new DataTypeDesc() {Name = "UInt16", Desc = "A 16-bit unsigned integer"} , new DataTypeDesc() {Name = "UInt32", Desc = "A 32-bit unsigned integer"} , new DataTypeDesc() {Name = "UInt64", Desc = "A 64-bit unsigned integer"} , new DataTypeDesc() {Name = "A", Desc = "The letter A in the alphabet"} , new DataTypeDesc() {Name = "B", Desc = "The letter B in the alphabet"} , new DataTypeDesc() {Name = "C", Desc = "The letter C in the alphabet"} , new DataTypeDesc() {Name = "D", Desc = "The letter D in the alphabet"} , new DataTypeDesc() {Name = "E", Desc = "The letter E in the alphabet"} , new DataTypeDesc() {Name = "F", Desc = "The letter F in the alphabet"} , new DataTypeDesc() {Name = "G", Desc = "The letter G in the alphabet"} , new DataTypeDesc() {Name = "H", Desc = "The letter H in the alphabet"} , new DataTypeDesc() {Name = "I", Desc = "The letter I in the alphabet"} , new DataTypeDesc() {Name = "J", Desc = "The letter J in the alphabet"} , new DataTypeDesc() {Name = "K", Desc = "The letter K in the alphabet"} , new DataTypeDesc() {Name = "L", Desc = "The letter L in the alphabet"} , new DataTypeDesc() {Name = "M", Desc = "The letter M in the alphabet"} , new DataTypeDesc() {Name = "N", Desc = "The letter N in the alphabet"} , new DataTypeDesc() {Name = "O", Desc = "The letter O in the alphabet"} , new DataTypeDesc() {Name = "P", Desc = "The letter P in the alphabet"} , new DataTypeDesc() {Name = "Q", Desc = "The letter Q in the alphabet"} , new DataTypeDesc() {Name = "R", Desc = "The letter R in the alphabet"} , new DataTypeDesc() {Name = "S", Desc = "The letter S in the alphabet"} , new DataTypeDesc() {Name = "T", Desc = "The letter T in the alphabet"} , new DataTypeDesc() {Name = "U", Desc = "The letter U in the alphabet"} , new DataTypeDesc() {Name = "V", Desc = "The letter V in the alphabet"} , new DataTypeDesc() {Name = "W", Desc = "The letter W in the alphabet"} , new DataTypeDesc() {Name = "X", Desc = "The letter X in the alphabet"} , new DataTypeDesc() {Name = "Y", Desc = "The letter Y in the alphabet"} , new DataTypeDesc() {Name = "Z", Desc = "The letter Z in the alphabet"} }; cboTypes.ItemsSource = aDataTypeDescs; } private void cboTypes_SelectionChanged(object sender, SelectionChangedEventArgs e) { DataTypeDesc oDesc = (DataTypeDesc)(cboTypes.SelectedItem); if (oDesc != null) UpdateDataText(oDesc); } } } 

DataTypeDesc.cs:

 using System; namespace ComboBox_Test { public class DataTypeDesc { public String Name { get; set; } public String Desc { get; set; } } } 

您需要编辑基本的ComboBox模板并更改名为Popup的元素的大小。 在此示例中,它已设置为100高,现在显示相同的固定高度弹出窗口,无论是初始列表还是选择后:

在此处输入图像描述

*注意:我使用Expression blend来编辑基本模板的副本(非常详细)。 由于元素部分被命名为“Popup”,您理论上可以编写代码以在可视化树中查找该部分并以此方式修改height属性。

下面更改页面的来源:

                                                                      Visible              Visible           Visible       True                                  true                                                                                         

我有这个完全相同的问题(实际上使用Silverlight 5,但仍然是相同的行为)并找到了一个不太可能的解决方案,不涉及修改模板(在我的情况下,我不想强​​迫Popup有一个固定的大小和方向)。

我发现如果我使用ComboBoxItems而不是自定义对象集合填充我的ComboBox,则不会发生下拉/选择/方向问题。 我真的不想这样做,因为我的原始设计是在ItemsSource,SelectedItem等上使用Binding。但是由于它修复了问题,我使用了ComboBoxItems并删除了绑定方法。

所以这里有几个快速的代码片段来说明差异 – 第一个使用自定义对象的集合并导致奇怪的行为(我的VehicleData类只是一个带有ID和Name以及其他一些属性的简单类):

 // List of Custom Objects - Results in inconsistent behavior ObservableCollection vehicleList = new ObservableCollection(); for (int i = 0; i < 80; i++) { vehicleList.Add(new VehicleData { ID = i, Name = string.Format("Vehicle {0}", i) }); } ComboBoxVehicles.DisplayMemberPath = "Name"; ComboBoxVehicles.ItemsSource = vehicleList; 

这里有一个很好的例子,无论添加了多少项以及ComboBox的定位是什么:

 // List of ComboBoxItems - WORKS List testValues = new List(); for (int i = 0; i < 80; i++) { testValues.Add(new ComboBoxItem { Content = "Item " + i, Tag = i }); } ComboBoxVehicles.ItemsSource = testValues; 

我知道这个问题已经得到了回答,但我想如果它帮助了其他人,我会发布这个问题。

根据您拥有的项目数量和可用的屏幕高度,您还可以设置ScrollViewer.VerticalScrollBarVisibility="Disabled" ,这将强制它向上打开,因为没有空间向下。