Я не вижу, что конкретно вы делаете здесь не так. Вы, вероятно, можете заставить это работать, если вы взломаете это достаточно.
Но это не правильный подход - по крайней мере, не настолько, насколько это важно для написания поддерживаемого и надежного кода WPF. Вы должны использовать привязку данных для заполнения этого элемента управления. После очень небольшого опыта в этом вы обнаружите, что это делает процесс разработки намного быстрее и проще, чем подход WinForms с кодом-WPF-как-будто-это-было-WinForms.
Вот как:
Создайте класс для хранения ваших элементов данных, например, с именем. Block
. Пусть он выставит свойства string Text
и bool IsBanned
.
Создайте ObservableCollection<Block>
и заполните его новыми Block
объектами, созданными из вашего источника данных.
Выставить коллекцию на переплет. Есть много способов сделать это; В приведенном ниже примере предполагается, что вы добавили его в словарь ресурсов окна с ключом Blocks
. Вы также можете реализовать свойство Blocks
в своем окне или (что я делаю почти каждый раз, когда создаю окно или пользовательский элемент управления в WPF), создать класс, который предоставляет свойство Blocks
и установить для DataContext
окна значение экземпляр этого класса.
Теперь поместите это в XAML вашего окна:
<ComboBox ItemsSource="{Binding {DynamicResource Blocks}}">
<ComboBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Text}">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="Black"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsBanned}">
<Setter Property="Foreground" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Вам на самом деле не нужно там Grid
(и вам не нужно устанавливать Grid.Column
, поскольку по умолчанию он равен 0); Я просто добавил это, чтобы пример более точно повторял то, что есть в вашем коде. Кроме того, я не устанавливаю свойство Tag
для ComboBoxItem
, но это потому, что ComboBox
SelectedItem
содержит фактический Block
экземпляр для этого элемента, что устраняет необходимость в Tag
свойство.
Поскольку вы используете ObservableCollection
, любые изменения, которые вы вносите в коллекцию (то есть добавление / удаление / переупорядочение ее элементов), автоматически отражаются на экране; Обязательство позаботится об этом за вас.
Если свойства элементов Text
или IsBanned
изменятся после заполнения коллекции, и вам потребуется ComboBox
, чтобы отразить эти изменения, вам нужно будет внедрить INotifyPropertyChanged
в Block
класс и пусть он поднимает PropertyChanged
в установщиках этих свойств.