ComboBox блокируется при запуске приложения - PullRequest
1 голос
/ 05 мая 2011

Хорошо, это странно (или я что-то тупо делаю).У меня есть поле со списком WPF, который заполняется массивом строк при загрузке формы (запуск приложения).Эта часть отлично работает.Важным моментом является то, что я пытаюсь изменить какую-либо информацию внутри указанного списка.Отладка говорит, что она меняется, но визуально ничего не показывается.

// Populate the combobox:
private void ComboBlocks()
{
    comboBox1.Items.Clear();
    string[,] _tmp = _kits.BlockIDNames;
    string[] _tmp1 = new string[_tmp.GetLength(0)];

    for (int i = 0; i < _tmp.GetLength(0); i++)
    {
        _tmp1[i] = _tmp[i, 0] + " - " + _tmp[i, 1];
    }

    foreach (string s in _tmp1)
    {
        string[] _tmpS1 = s.Split(new char[] { '-' });
        int _tmpS2 = Convert.ToInt32(_tmpS1[0].Trim());
        bool _banneditem = _cbi.BannedItemExists(_tmpS2);
        if (_banneditem == true)
            AddComboItem(s, true);
        else
            AddComboItem(s);
    }

    if (comboBox1.Items.Count > 0)
        comboBox1.SelectedIndex = 0;            
}

// Add item to combobox:
private void AddComboItem(string _text,bool _redtext = false)
{
    Grid grid = new Grid();
    grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });

    TextBlock text = new TextBlock();
    text.Text = _text;

    if (_redtext == true)
        text.Foreground = Brushes.Red;
    else
        text.Foreground = Brushes.Black;

    grid.Children.Add(text);
    Grid.SetColumn(text, 0);

    ComboBoxItem comboBoxItem = new ComboBoxItem();
    comboBoxItem.Content = grid;
    comboBoxItem.Tag = _text;

    comboBox1.Items.Add(comboBoxItem);
}

Кроме того, я довольно новичок в C #, поэтому, если есть что-то, что я делаю неправильно или неэффективно, укажите это.

Большое спасибо.

РЕДАКТИРОВАТЬ: перебор каждого из них и изменение текстового значения, вероятно, будет такой же работой, как и получение информации из другого массива.Он должен был бы проверить каждый элемент в массиве и, если он существует, закрасить его красным, если нет, закрасить его черным.

1 Ответ

0 голосов
/ 05 мая 2011

Я не вижу, что конкретно вы делаете здесь не так. Вы, вероятно, можете заставить это работать, если вы взломаете это достаточно.

Но это не правильный подход - по крайней мере, не настолько, насколько это важно для написания поддерживаемого и надежного кода WPF. Вы должны использовать привязку данных для заполнения этого элемента управления. После очень небольшого опыта в этом вы обнаружите, что это делает процесс разработки намного быстрее и проще, чем подход WinForms с кодом-WPF-как-будто-это-было-WinForms.

Вот как:

  1. Создайте класс для хранения ваших элементов данных, например, с именем. Block. Пусть он выставит свойства string Text и bool IsBanned.

  2. Создайте ObservableCollection<Block> и заполните его новыми Block объектами, созданными из вашего источника данных.

  3. Выставить коллекцию на переплет. Есть много способов сделать это; В приведенном ниже примере предполагается, что вы добавили его в словарь ресурсов окна с ключом 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 в установщиках этих свойств.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...