2013-06-30 11 views
5

Я хочу отфильтровать ObservableCollection подмножеством на основе типа (типа AddPoint) и хочу, чтобы он упорядочивался по возрастанию без дубликатов. Мой базовый класс - это ModelBase, w/sub-classes AddPoint, Time, Repeat и т. Д.. ObservableCollection MotionSequenceCollection будет заполнен с этими типами в любом порядке, а некоторые будут дублироваться.WPF Binding filter ObservableCollection ICollectionView to Combobox

Я пробовал несколько раз и показывал их ниже в свойстве ICollectionView, которое я «вытащил» из: Bind subset of collection.

Observable СБОР

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://stackoverflow.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 stackoverflow and not sure how that got there in the first place. 
      //source.Filter = p => (p as ModelBase).GetType() == "AddPoint"; 
      //return source; 

      return location; 
     } 
    } 

ответ

2

Все коллекции имеют CollectionView по умолчанию. 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 

    } 
} 
+0

Честно говоря, я много борюсь с этим. Я изначально пошел по пути @ makc с CollectionViewSource_FIlter и нашел несколько примеров, чтобы помочь, но проблема заключалась в том, чтобы сделать список отдельным() - это было 2 дня назад, и моя голова туманна. Фильтр выглядит так: – FloppyDisk

+0

Мне нужно пересмотреть свой комментарий. Я получил ваше решение и много узнал о коллекцииviewsource .. Проблема в том, что если в combobox (отфильтрованное представление) есть дубликаты и только одно шоу, когда я редактирую его в коллекции, он не обновляется, добавляя новое отредактированная запись. Если есть только один, то это обновление, как ожидается после propertychanged. Вот почему я пошел по пути linq, но это оказалось катастрофическим. – FloppyDisk

+0

@FloppyDisk Я очень рад, что вы просто не скопировали прошлое, но прочитали и изучили :), я не уверен, что понимаю, что проблема полностью пытается создать небольшой самостоятельный пример, и я думаю, что это стоит нового вопроса ... – makc

1

Фильтрация по типу легко. Это должно работать:

location.Filter = p => p.GetType() == typeof(AddPoint); 

Сортировка также довольно проста. Все, что вам нужно сделать, это реализовать IComparer и присвоить его CustomSort.

Нет простого способа удалить дубликаты tho (не то, что я знаю). Я предлагаю вам сделать это в другом месте. Например, вы можете отличить свою базовую коллекцию.

+0

я изменил тактику и попытался создать подмножество в ObservableCollection с LINQ. Затем привяжите это к моему представлению. Это был серьезный пробег. У меня есть ошибка, которая говорит, что мне нужно реализовать IComparer. Вглядываясь в это. Спасибо за ответ. – FloppyDisk

Смежные вопросы