DataTemplate с TargetNullValue в ListBox

У меня есть следующий шаблон данных в списке

<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 по умолчанию. Я получаю тот же эффект, если привязываюсь к нужному полю с помощью параметра «Путь», и я подумал, что это будет легче читать.


person Bryan Anderson    schedule 07.01.2009    source источник
comment
Кажется, что элемент нельзя выбрать с помощью клавиатуры, поскольку выделение меняется на пунктирную границу вместо синего фона. Очень странно.   -  person Ray Booysen    schedule 08.01.2009
comment
Он делает это, но если вы поместите точку останова в установщик, он будет вызван, поэтому выбор действительно произойдет, а список просто выделит выделение по-другому.   -  person Bryan Anderson    schedule 08.01.2009
comment
Я только что запустил Snoop через контроль и не могу сказать разницы. Все элементы являются ListBoxItems, но я не могу заметить разницы, и я просто провел некоторое время в Reflector, чтобы попытаться увидеть какие-либо изменения в том, как работает рендеринг.   -  person Ray Booysen    schedule 08.01.2009


Ответы (3)


Если вы ищете решение, возможно, вы найдете здесь то, что хотите: Почему я не могу выбрать нулевое значение в ComboBox?

Combobox ведет себя так же, как ListBox.

person redjackwong    schedule 23.02.2009
comment
Спасибо. Я заметил этот вопрос, когда он был первоначально опубликован, и прокомментировал им, что ответы будут такими же. - person Bryan Anderson; 23.02.2009

В приведенном ниже блоге представлено хорошее решение с использованием Attached Property, которое у меня хорошо работает.

http://danylaporte.blogspot.com/2008/07/wpf-combobox-and-null-values.html

person siddardha    schedule 04.01.2012

Я думаю, что происходит следующее:

Я предполагаю, что 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.

person Rhys    schedule 08.01.2009
comment
К сожалению, я уже привязываюсь к более сложному объекту. Так что это не проблема, допускающая значение NULL, как вы предлагаете. Спасибо за идею, обновлю свой вопрос. - person Bryan Anderson; 08.01.2009