Нажатие на ComboBoxItem с привязкой к данным не обновляет родительский ComboBox

Я привязываю словарь к элементу ComboBox ItemSource. Все привязывается правильно, однако, когда я запускаю программу, нажимаю раскрывающийся список, затем нажимаю на элемент... ничего не происходит.

Другая полезная информация: когда я щелкаю текст каждого элемента, я вижу слабую рамку/рамку вокруг текста. Если я нажму внутри поля, ничего не произойдет. Если я нажму за пределами поля, все будет работать так, как ожидалось. Мысли?

Мой xaml-код:

<ComboBox Name="PayloadDrop">
   <ComboBox.ItemTemplate>
      <ItemContainerTemplate>
         <ComboBoxItem Tag="{Binding Path=Key}" 
             Content="{Binding Path=Value}" />
         </ItemContainerTemplate>
      </ComboBox.ItemTemplate>
</ComboBox>

И мой код позади:

Dim PayloadDictionary As New Dictionary(Of Int16, String) From _
        {{0, "Some payload text"}, {1, "Path to a payload file"}}

PayloadDrop.ItemsSource = PayloadDictionary

Ниже приведен скриншот того, как выглядит мое поле со списком...

скриншот


person Lucas Bailey    schedule 17.07.2015    source источник
comment
Вместо ItemContainerTemplate используйте DataTemplate. Ничего не происходит, вы имеете в виду, что выбранный элемент не отображается в ComboBox?   -  person Maximus    schedule 17.07.2015
comment
Под «Ничего не происходит» я имел в виду, что буквально ничего не произойдет. Ни одно из моих событий onclick не сработает (не показано в приведенном выше коде), выбранный элемент в поле со списком не изменится на элемент, который я щелкнул, и раскрывающийся список больше не будет скрыт. По сути, скриншот, который вы видите выше, просто останется там ... Как только я изменил свой код с ComboBoxItem на TextBlock и атрибут Content на Text, все заработало отлично.   -  person Lucas Bailey    schedule 21.07.2015


Ответы (2)


У меня никогда не было большого опыта работы с ItemContainerTemplate, но, насколько я понимаю, с DataTemplate дело обстоит так же. (Ресурсы, MenuBase или StatusBar не упоминаются)

У вас есть коллекция элементов KeyValuePair как ItemsSource. KeyValuePair не является ComboBoxItem, поэтому ComboBox решает создать для него контейнер — ComboBoxItem. Этому контейнеру нужен способ отображения данных элемента, и вы установили для этого ItemTemplate, в результате внутри контейнера создается другой ComboBoxItem. Итак, у вас есть ComboBoxItem внутри ComboBoxItem. Внешний ComboBoxItem связан с ComboBox, поэтому ComboBox получает клики. Внутренний ComboBoxItem отображается со слабой рамкой и отключен, поэтому реакция на события щелчка отсутствует.
Есть два возможных способа изменить ваш xaml: либо использовать правильный DataTemplate для ItemTemplate, либо Style для ItemContainerStyle. Насколько я понимаю, ваша задача — отображать значение, но при этом сохранять информацию о ключе (идентификаторе какого-либо вида), поэтому вы должны использовать правильный DataTemplate:

<ComboBox x:Name="PayloadDrop">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Value, Mode=OneTime}"/>
                </DataTemplate>
            </ComboBox.ItemTemplate>
</ComboBox>

В этом случае ComboBox будет отображать только значение. Вы можете получить к нему доступ с помощью свойства SelectedValue. Свойство SelectedItem будет содержать базовый KeyValuePair. Поскольку KeyValuePair не реализует INotifyPropertyChanged, важно использовать Mode=OneTime, чтобы избежать утечек памяти.

person Aloraman    schedule 17.07.2015
comment
Уггг... Изменение его с комбинированного элемента на текстовый блок исправило это... так много потраченного времени... Большое спасибо. Также спасибо @SamTheDev. Очевидно, я не понимал, что comboboxitem был создан автоматически... - person Lucas Bailey; 17.07.2015

вам не нужно определять ComboboxItem внутри DataTemplate, так как он будет создан неявно

<ComboBox Name="PayloadDrop" VerticalAlignment="Center" HorizontalAlignment="Center" Width="200">
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Tag="{Binding Path=Key}" Padding="0" Margin="0"
         Text="{Binding Path=Value}" >                       
                </TextBlock>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>
person SamTh3D3v    schedule 17.07.2015