Новый текст никогда не будет присутствовать в элементах внутри ComboBox
. Ниже приведен полный код XAML +, который работает не так, как я хочу. Я пытаюсь добиться того, чтобы пользователь выбрал фактическую группу элементов из поля со списком или элемент No Group
(курсив, выделен серым цветом), который должен применяться в качестве пустой строки в текстовое поле внутри ComboBox
.
Я тоже пробовал:
- с
StaysOpenOnEdit="True"
(с тем же результатом) и
- путем обработки события
Selected
"click me"
ComboBoxItem
(обработчик события вызывается до изменения свойств Text
или SelectedItem
ComboBox).
1022 * XAML *
<Window x:Class="cs_wpf_test_12.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:cs_wpf_test_12"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<StackPanel Orientation="Vertical">
<ComboBox SelectionChanged="ComboBox_SelectionChanged"
IsEditable="True">
<ComboBoxItem>test</ComboBoxItem>
<ComboBoxItem Foreground="Gray">click me</ComboBoxItem>
</ComboBox>
</StackPanel>
</Window>
Код-за
internal bool HandlingSelectionChange = false;
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (HandlingSelectionChange)
{
return;
}
HandlingSelectionChange = true;
var cb = sender as ComboBox;
if (cb.Text == "click me")
{
cb.Text = "";
e.Handled = true;
}
HandlingSelectionChange = false;
}
Ожидается: когда пользователь нажимает на элемент "щелкни меня" в раскрывающемся списке, текст ComboBox
становится пустой строкой. Остальные элементы при нажатии должны копировать свой текст в обычном текстовом поле ComboBox
.
.
Фактический:
- Запустите программу.
- Выберите пункт "нажмите меня".
- Текст изменится на «щелкни по мне» (не будет выделен серым цветом) вместо «».
- Нажмите на пункт «Тест».
- Текст меняется на "" (пустая строка) вместо "test".
- Снова нажмите на пункт «Тест».
- Текст меняется на «тест».
Обновление
Я хочу использовать MVVM, но я все еще начинающий. У меня есть несколько ComboBox
, как показано выше внутри DataGridTemplateColumn
, и для каждого из ComboBox
(которое должно иметь одинаковое раскрывающееся содержимое), я думаю, что у меня должен быть ViewModel для каждого из ComboBoxItem
s. Если возможно, я бы хотел узнать, как правильно использовать MVVM в этой ситуации.
Большой XAML
<DataGridTemplateColumn Header="Group Name">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Label Content="{Binding GroupName, Mode=OneWay}">
</Label>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox IsEditable="True" StaysOpenOnEdit="True"
ItemsSource="{Binding Path=Clocks.GroupsVM,
RelativeSource={RelativeSource AncestorType=local:ClockDataGrid}}"
PreviewKeyDown="ComboBox_PreviewKeyDown"
SelectionChanged="ComboBox_SelectionChanged"
Text="{Binding GroupName}">
<ComboBox.Resources>
<Style TargetType="ComboBoxItem">
<Setter Property="FontStyle" Value="{Binding FontStyle}"/>
<Setter Property="Foreground" Value="{Binding Foreground}"/>
</Style>
</ComboBox.Resources>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
Большой код-позади
private void ComboBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
var cb = sender as ComboBox;
if ((e.Key == Key.Return ||
e.Key == Key.Enter) &&
cb.Text != "")
{
bool duplicate = false;
foreach (ClockGroupVM vm in Clocks.GroupsVM)
{
if (vm.Name == cb.Text)
{
cb.SelectedItem = vm;
duplicate = true;
break;
}
}
if (duplicate)
{
return;
}
// create a ClockGroupM and corresponding ClockGroupVM
// (ClockGroupVM inherits from ClockGroupM)
var cvm = new ClockGroupVM()
{
Name = cb.Text
};
Clocks.Groups.Insert(0, cvm);
cb.SelectedItem = cvm;
}
}
internal bool HandlingSelectionChange = false;
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (HandlingSelectionChange)
{
return;
}
HandlingSelectionChange = true;
var cb = sender as ComboBox;
//if (cb.SelectedItem is the VM with Style != Normal)
ClockGroupVM foundVM = null;
foreach (ClockGroupVM vm in Clocks.GroupsVM)
{
if (vm.FontStyle != FontStyles.Normal &&
ReferenceEquals(cb.SelectedItem, vm))
{
foundVM = vm;
break;
}
}
if (foundVM != null)
{
cb.Text = "";
e.Handled = true;
}
HandlingSelectionChange = false;
}