我们举个例子吧。
<ComboBox x:Name="cmbTest" IsEditable="False">
<ComboBoxItem Content="7"/>
<ComboBoxItem Content="ab"/>
<ComboBoxItem Content="abc 1"/>
<ComboBoxItem Content="abc"/>
<ComboBoxItem Content="8 (1)"/>
<ComboBoxItem Content="8 (2)"/>
<ComboBoxItem Content="9"/>
<ComboBoxItem Content="8"/>
<ComboBoxItem Content="100"/>
<ComboBoxItem Content="10"/>
<ComboBoxItem Content="1"/>
</ComboBox>
然后尝试代码中的每一行:
cmbTest.Text = "7"; //Correctly selected, .SelectedIndex = 0
cmbTest.Text = "ab"; //Correctly selected, .SelectedIndex = 1
cmbTest.Text = "abc 1"; //Correctly selected, .SelectedIndex = 2
cmbTest.Text = "abc"; //Nothing selected, .SelectedIndex = -1
cmbTest.Text = "8 (1)"; //Correctly selected, .SelectedIndex = 4
cmbTest.Text = "8 (2)"; //Correctly selected, .SelectedIndex = 5
cmbTest.Text = "9"; //Correctly selected, .SelectedIndex = 6
cmbTest.Text = "8"; //Nothing selected, .SelectedIndex = -1
cmbTest.Text = "100"; //Correctly selected, .SelectedIndex = 8
cmbTest.Text = "10"; //Nothing selected, .SelectedIndex = -1
cmbTest.Text = "1"; //Nothing selected, .SelectedIndex = -1
未正确选择以任何先前项目的子字符串开头的任何项目。
IsEditable=True
时更危险。该项目已正确显示/选择,但返回 -1 作为其 SelectedIndex
(与上面相同)。
除了迭代和使用
SelectedIndex
来选择一个项目(我做了什么来解决这个问题),还有没有办法解决这个问题?也许我错过了什么?
我还经历了默认组合框糟糕的用户体验配置。
我不知道你想要的是否正确,但我是这样解决的。
// override default ComboBox
// MyComboBox.cs
public class MyComboBox : ComboBox
{
private TextBox PART_EditableTextBox;
public override void OnApplyTemplate()
{
if (PART_EditableTextBox != null)
PART_EditableTextBox.LostFocus -= PART_EditableTextBox_LostFocus;
base.OnApplyTemplate();
#warning it works only when 'IsEditable' property is 'True'
FrameworkElement root = GetVisualChild(0) as FrameworkElement;
PART_EditableTextBox = (TextBox)root.FindName("PART_EditableTextBox");
PART_EditableTextBox.LostFocus += PART_EditableTextBox_LostFocus;
}
private void PART_EditableTextBox_LostFocus(object sender, RoutedEventArgs e)
{
try
{
if (PART_EditableTextBox == null) return;
else if (string.IsNullOrWhiteSpace(DisplayMemberPath))
if (SelectedItem is ComboBoxItem comboBoxItem)
PART_EditableTextBox.Text = comboBoxItem.Content?.ToString();
else
PART_EditableTextBox.Text = SelectedItem?.ToString();
else PART_EditableTextBox.Text = SelectedItem?.GetType().GetProperty(DisplayMemberPath)?.GetValue(SelectedItem)?.ToString();
}
catch { }
}
}
这个想法的核心是当用户认为他们已经做出选择时向用户提供适当的反馈(当“LostFocus”事件触发时)。
<Window x:Class="test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:test"
Title="MainWindow" Height="450" Width="800">
<StackPanel>
<local:MyComboBox IsEditable="True">
<ComboBoxItem Content="7"/>
<ComboBoxItem Content="ab"/>
<ComboBoxItem Content="abc 1"/>
<ComboBoxItem Content="abc"/>
<ComboBoxItem Content="8 (1)"/>
<ComboBoxItem Content="8 (2)"/>
<ComboBoxItem Content="9"/>
<ComboBoxItem Content="8"/>
<ComboBoxItem Content="100"/>
<ComboBoxItem Content="10"/>
<ComboBoxItem Content="1"/>
</local:MyComboBox>
<TextBox/>
</StackPanel>