У меня есть следующий шаблон данных в списке
<ListBox Grid.Column="1" Grid.Row="2" ItemsSource="{Binding People}" SelectedItem="{Binding SelectedPerson}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock OverridesDefaultStyle="True"
Background="{x:Null}"
Margin="0"
Padding="0"
IsHitTestVisible="True"
Text="{Binding TargetNullValue=None}"
/>
</DataTemplate>
</ListBox.ItemTemplate>
This works perfectly, displaying "None" in place of any Null (Nothing) values in the bound list. The problem is that I can't click on the Null values to select them. Selection with the keyboard works perfectly, just not with a mouse. What can I do to make the Null values in the list act just like any other value?
Изменить: я также должен добавить, что я могу изменить фон TextBlock на красный, и он будет отображаться так же, как и другие, поэтому я не думаю, что это тот случай, когда не на что нажимать. Я также посмотрел на это с помощью Snoop, и я не вижу никаких атрибутов в визуальном дереве, которые отличаются между нулевым элементом и обычным элементом.
Изменить 2: я должен добавить, что люди на самом деле класс, представляющий таблицу базы данных. Он использует метод ToString для отображения объектов People по умолчанию. Я получаю тот же эффект, если привязываюсь к нужному полю с помощью параметра "Путь", и я подумал, что это будет легче читать.
Ответ 3 · Rhys
Я думаю, что происходит следующее:
Я предполагаю, что ItemSource представляет собой простую коллекцию значений простых строк (т.е. не инкапсулированных в другой класс). Когда вы нажимаете кнопку мыши на объекте, программный код копирует ссылку на объект элемента в коллекции в поле SelectedItem списка.
поэтому, если коллекция: - "Fred", null, "Jane", "Mary" и вы нажимаете мышью на "Fred", тогда ссылка на объект "Fred" копируется в SelectedItem. Если вы нажмете на второй элемент, эта ссылка на объект (пустая) копируется в SelectedItem.
Проблема в том, что значение NULL в SelectedItem фактически означает особый случай, когда ни один элемент не выбран.
Вы не получите "None", скопированное в SelectedItem, даже если оно указано в вашем атрибуте TargetNullValue. Это просто визуальное представление, когда элемент коллекции содержит значение NULL. Список интересует только объектные ссылки коллекции, а не то, что отображается в пользовательском интерфейсе.
Один из способов обойти это - создать ненулевую коллекцию объектов со строковым полем, называемым "имя".
e.g.
class People
{
string Name {get;set;}
}
...
...
var list = new List<People> {new People {Name = "Fred"},
new People {Name = null},
new People {Name = "Jane"},
};
Тогда это будет означать, что ни один элемент в списке не будет иметь значения NULL.
Затем в привязке DataTemplate используйте: -
Text="{Binding Path=Name, TargetNullValue=None}"
SelectedItem для каждого элемента теперь будет отличаться от NULL, даже если имя NULL, но недостатком для вас является то, что SelectedItem теперь больше не является строкой с выбранным именем, а является ссылкой на выбранный объект People.