WPF Привязка отфильтрованного ObservableCollection ICollectionView к Combobox
Я хочу отфильтровать ObservableCollection для подмножества на основе типа (типа AddPoint) и хочу, чтобы он упорядочивался по возрастанию без дубликатов. Мой базовый класс - ModelBase, с подклассами AddPoint, Time, Repeat и т. Д.... ObservableCollection MotionSequenceCollection будет заполняться этими типами в любом порядке, а некоторые будут дубликатами.
Я пробовал несколько раз и показывал их ниже в свойстве ICollectionView, из которого я "извлек": подмножество подбора коллекции.
НАБЛЮДАЕМАЯ КОЛЛЕКЦИЯ
private ObservableCollection<ModelBase> _motionSequenceCollection =
new ObservableCollection<ModelBase>();
public ObservableCollection<ModelBase> MotionSequenceCollection
{
get
{
return _motionSequenceCollection;
}
set
{
if (_motionSequenceCollection == value)
{
return;
}
var oldValue = _motionSequenceCollection;
_motionSequenceCollection = value;
// Update bindings, no broadcast
RaisePropertyChanged();
}
}
public ICollectionView Location
{
get
{
var location = CollectionViewSource.GetDefaultView(_motionSequenceCollection);
//DOES NOT WORK. PROBLEM: GetType() creates type of system.type() and AddPoint, which don't work. Need a cast, or something??
// found at https://stackru.com/questions/9621393/bind-subset-of-collection The problem is that there is an error:
// Cannot apply operator '==' to operands of type 'System.Type' and 'MotionSeq.Model.AddPoint',
// candidates are:
// bool ==(System.Reflection.MemberInfo, System.Reflection.memberInfo) (in class MemberInfo)
// bool ==(System.type, System.Type) (in class Type)
//location.Filter = p => (p as ModelBase).GetType() == AddPoint;
//DOES NOT WORK. PROBLEM: Affects the main collection and won't let TIME type added.
//location.Filter = o1 => (o1 is AddPoint);
//DOES NOT WORK. PROBLEM: Sorts fine, but also sorts MotionSequenceCollection!! What up w/ that!?
//location.SortDescriptions.Add(new SortDescription("AddPointClassName", ListSortDirection.Ascending));
//DOES NOT WORK. PROBLEM: MotionSequenceCollection does not update.
//location.Filter = p => (p as ModelBase) == AddPoint;
//DOES NOT WORK. PROBLEM: Source is not instantiated(?) and exmaple from stackru and not sure how that got there in the first place.
//source.Filter = p => (p as ModelBase).GetType() == "AddPoint";
//return source;
return location;
}
}
2 ответа
Все коллекции имеют коллекцию по умолчанию. WPF всегда привязывается к представлению, а не к коллекции. Если вы связываете напрямую с коллекцией, WPF фактически связывается с представлением по умолчанию для этой коллекции. Это представление по умолчанию является общим для всех привязок к коллекции, в результате чего все прямые привязки к коллекции совместно используют характеристики сортировки, фильтра, группы и текущего элемента одного представления по умолчанию.
попробуйте создать CollectionViewSource и установить его логику фильтрации следующим образом:
//create it as static resource and bind your ItemsControl to it
<CollectionViewSource x:Key="csv" Source="{StaticResource MotionSequenceCollection}"
Filter="CollectionViewSource_Filter">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="YYY"/>
</CollectionViewSource.GroupDescriptions>
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="YYY" Direction="Ascending"/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
private void CollectionViewSource_Filter(object sender, FilterEventArgs e)
{
var t = e.Item as ModelBase;
if (t != null)
{
//use your filtering logic here
}
}
Фильтрация по типу проста. Это должно работать:
location.Filter = p => p.GetType() == typeof(AddPoint);
Сортировка тоже довольно проста. Все, что вам нужно сделать, это реализовать IComparer
и назначить его CustomSort
свойство коллекционного вида.
Нет простого способа удалить дубликаты, хотя (не то, что я знаю). Я предлагаю вам сделать это в другом месте. Например, вы можете выделить свою базовую коллекцию.