2015-12-13 3 views
0

Я построил фильтрацию Behavior для CollectionViewSource, она обычно работает и используется следующим образом:Связывание свойство а UIElement от статического ресурса

<CollectionViewSource Source="{Binding ListOfStuff}" x:Key="FilteredListOfStuff"> 
    <i:Interaction.Behaviors> 
     <behaviors:FilterBehavior> 
      <behaviors:PropertyFilter Property="SomePropName"> 
       <behaviors:TextFilter FilterText="filter text"/> 
      </behaviors:PropertyFilter> 
     </behaviors:FilterBehavior> 
    </i:Interaction.Behaviors> 
</CollectionViewSource> 

Проблема заключается в том, что, как я теперь понимаю, я могу 't связывает свойства фильтра с UIElements, потому что CollectionViewSource является статическим ресурсом.

То, что я хотел, и теперь не может сделать это:

<behaviors:TextFilter FilterText="{Binding ElementName=TheSearchTextBox, Path=Text}"/> 

Есть ли способ обойти это? Мое поведение фильтрации основано на использовании события CollectionViewSource.Filter, есть ли хороший и чистый способ фильтрации без «CollectionViewSource»? То есть, добавьте поведение фильтра непосредственно в ItemsControl s (DataGrid, ListBox и т. Д.)?

я могу решить эту проблему путем связывания TheSearchTextBox.Text и FilterText к тому же ViewModel собственности, но такого рода перерывов MVVM как фильтрация является чисто «View» действие ...

EDIT Добавление поведения фильтра код:

[ContentPropertyAttribute("Filters")] 
    public class FilterBehavior : Behavior<CollectionViewSource> 
    { 

     private List<IFilter> _filters; 
     public List<IFilter> Filters 
     { 
      get 
      { 
       return _filters ?? 
          (_filters = new List<IFilter>()); 
      } 
     } 

     protected override void OnAttached() 
     { 
      base.OnAttached(); 
      AssociatedObject.Filter += CollectionViewSource_Filter; 
     } 

     protected override void OnDetaching() 
     { 
      base.OnDetaching(); 
      AssociatedObject.Filter -= CollectionViewSource_Filter; 
     } 

     void CollectionViewSource_Filter(object sender, FilterEventArgs e) 
     { 
      if (Filters != null) 
      { 
       e.Accepted = Filters.All((f) => !f.IsEnabled || f.Filter(e.Item)); 
      } 
     } 
    } 
+0

Почему «CollectionViewSource» должен быть статическим ресурсом? Я предполагаю, что, поскольку вы хотите привязываться к некоторому элементу визуального дерева, вы будете использовать его только один раз? Таким образом, вы можете определить его непосредственно в визуальном дереве, где привязка должна работать. – LionAM

+0

Можете ли вы опубликовать код своего поведения? Вы можете напрямую вставить Поведение в элемент управления, где это необходимо. – AnjumSKhan

+0

Вы всегда можете использовать Mode = OneWay для отправки значения из TextBox в ваш staticresource, если ваш StaticResource является DepObject. – AnjumSKhan

ответ

1

Нам нужны определённый пользователь строка фильтра в нашем FilterText свойства behaviors:TextFilter класса.

Создать простой класс FilterPropertyElement:

public class FilterPropertyElement : FrameworkElement 
    { 
     public override string ToString() 
     { 
      return Tag.ToString(); 
     } 
    }  

Объявить ресурса,

<Window.Resources> 
     <local:FilterPropertyElement x:Key="FilterPropertyKey" Tag="some filter key value"/> 
</Window.Resources> 

Измените критерии TextFilter использовать ресурс. :

<behaviors:TextFilter FilterText="{Binding Path=Tag, Source={StaticResource FilterPropertyKey}}"/> 

Нанести привязки к TextBox от где получить критерии фильтрации

<TextBox Text="{Binding Path=Tag, Source={StaticResource FilterPropertyKey}, UpdateSourceTrigger=LostFocus}" /> 
+0

Итак, я не сделал именно то, что вы предлагали, но достаточно близко, чтобы принять ответ. Я напишу подробности о том, что я сделал в другом ответе для будущих зрителей. – pseudoDust

+0

@pseudoDust ура! больше вопросов приветствуется! – AnjumSKhan

0

То, что я в конечном итоге делает, вдохновленный ответ AnjumSKhan, в том, чтобы добавить фильтр к коллекции Руд Resources и имеют TextBox связываются с ней:

<UserControl.Resources> 
    <b:TextFilter x:Key="SearchTextFilter" /> 
    <CollectionViewSource Source="{Binding ListOfStuff}" x:Key="FilteredListOfStuff"> 
     <i:Interaction.Behaviors> 
      <b:FilterBehavior> 
       <b:PropertyFilter Property="SomePropName"> 
        <StaticResource ResourceKey="SearchTextFilter"/> 
       </b:PropertyFilter> 
      </b:FilterBehavior> 
     </i:Interaction.Behaviors> 
    </CollectionViewSource> 
</UserControl.Resources> 
. 
. 
. 
<TextBox Text="{Binding Path=FilterText, Source={StaticResource SearchTextFilter}, Mode=OneWayToSource}"/> 

Это еще не так чист, как хотелось бы, но это лучшее, что я могу придумать, если кто-то есть лучше решение, пожалуйста, дайте мне знать.

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