Do Вы знаете, почему это броситьфильтрация CollectionViewSource приносит пустой результат будет бросать исключение
An unhandled exception of type 'System.NullReferenceException' occurred in PresentationFramework.dll
Additional information: Object reference not set to an instance of an object.
Когда я пытаюсь фильтровать CollectionViewSource, что не дает достоверных строк?
Код следующий.
XAML:
<ComboBox SelectedItem="{Binding Item}" ItemsSource="{Binding Items}" IsSynchronizedWithCurrentItem="True" />
первый код:
public class Model : INotifyPropertyChanged
{
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
public string Item { get; set; }
public ICollectionView Items { get; set; }
public Model()
{
Items = CollectionViewSource.GetDefaultView(new ObservableCollection<string>(new List<string> { "aaa", "bbb" }));
}
public void DoFirst()
{
Items.Filter = o => ((string)o).StartsWith("a");
}
public void DoSecond()
{
Items.Filter = o => false;
}
public event PropertyChangedEventHandler PropertyChanged;
}
DoFirst() работает. DoSecond() нет. Исключение происходит от линии Items.Filter = o => false;
.
Если я удалить уведомит свойство вещи, он не будет бросать исключение, но другая интересная ошибка происходит:
второй код:
public class Model
{
public string Item { get; set; }
public ICollectionView Items { get; set; }
public Model()
{
Items = CollectionViewSource.GetDefaultView(new ObservableCollection<string>(new List<string> { "aaa", "bbb" }));
}
public void DoFirst()
{
Items.Filter = o => ((string)o).StartsWith("a");
}
public void DoSecond()
{
Items.Filter = o => false;
}
}
Пустой список отображается. Это верно. Но тогда, когда я DoFirst(), в списке отображается «aaa» справа, он не выбран по умолчанию. IsSynchronizedWithCurrentItem не срабатывает.
Если я попытаюсь защитить фильтр от NRE, произойдет третий вид поведения.
третий код:
public class Model : INotifyPropertyChanged
{
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
public string Item { get; set; }
public ICollectionView Items { get; set; }
public Model()
{
Items = CollectionViewSource.GetDefaultView(new ObservableCollection<string>(new List<string> { "aaa", "bbb" }));
}
public void DoFirst()
{
try
{
Items.Filter = o => ((string)o).StartsWith("a");
} catch (NullReferenceException) { }
}
public void DoSecond()
{
try
{
Items.Filter = o => false;
} catch (NullReferenceException) { }
}
public event PropertyChangedEventHandler PropertyChanged;
}
В этом случае, выбираемые элементы в выпадающем списке прав. После DoSecond() список пуст, но последний выбранный элемент по-прежнему выбран ... После DoSecond() DoFirst() также выбрасывает NullReferenceException
.
Если мы установим текущий элемент в нуль и назовем OnPropertyChanged
, то стабильность второго кода будет достигнута. Свойство IsSynchronizedWithCurrentItem
для выбора действительного Item
из ComboBox все еще потеряно. В следующем коде, если я вызываю DoFirst()
, DoThird()
, тогда будет выбран «bbb». После установки Item
обнулить (назовем DoSecond()
раньше), он не будет выбрать "БББ":
четвертый код:
public class Model : INotifyPropertyChanged
{
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
public string Item { get; set; }
public ICollectionView Items { get; set; }
public Model()
{
Items = CollectionViewSource.GetDefaultView(new ObservableCollection<string>(new List<string> { "aaa", "bbb" }));
}
public void DoFirst()
{
Items.Filter = o => ((string)o).StartsWith("a");
}
public void DoSecond()
{
Item = null;
OnPropertyChanged("Item");
Items.Filter = o => false;
}
public void DoThird()
{
Items.Filter = o => ((string)o).StartsWith("b");
}
public event PropertyChangedEventHandler PropertyChanged;
}
Br, Мартон
[Что такое 'NullReferenceException' и как его исправить?] (http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do- i-fix-it) –
Первая версия кода не использует 'OnPropertyChanged' в любой точке. Вы что-то убрали? – Nitram
SonerGönül: Спасибо, но я уже знаю, что такое исключение для ссылки. Проблема не связана с постами, которые вы цитируете. Я ожидаю, что выбранный элемент будет иметь значение null после фильтрации. Но почему это происходит, только если класс реализует INotifyPropertyChanged? @ Нитрам: Вы видите правильно. Нет вызова OnPropertyChanged. Я создал минимальный пример, и ему не нужен вызов OnPropertyChanged, но он по-прежнему ведет себя по-другому. – ntohl