В форме OrdersView клиента можно выбирать с помощью раскрываемого списка элемента управления ComboBox. Это удобно, но клиентская база фирмы Northwind обширна, и оператору требуется средство быстрого поиска по списку: по наименованию фирмы, по имени контактного лица, по местоположению. С библиотекой ItemsFilter это несложно.

How use.

OrdersView.xaml
<ComboBox x:Name="customerComboBox"
         ItemsSource="{Binding Customers,
                               Source={StaticResource Workspace}}"
         SelectedItem="{Binding Customer,
                                Converter={StaticResource NullToUnsetValueConverter}}"
         Style="{DynamicResource ComboBoxStyle}" />

 How work.
Создаем пару классов – специализированный фильтр CustomersComboBoxFilter и его инициализатор CustomersComboBoxFilterInitializer:

CustomersComboBoxFilter.cs
[View(typeof(StringFilterView))]
// Define specialized filter for CustomersComboBox.
public sealed class CustomersComboBoxFilter : StringFilter, IFilter {
    private static StringBuilder sb = newStringBuilder(6);
    internal CustomersComboBoxFilter()
        // To search for combine the values of several properties.
        : base(item =>
        {
            Customer customer = (Customer)item;
            sb.Clear();
            sb.Append(customer.City);
            sb.Append(',');
            sb.Append(customer.Code);
            sb.Append(',');
            sb.Append(customer.ContactName);
            sb.Append(',');
            sb.Append(customer.Country);
            sb.Append(',');
            sb.Append(customer.Name);
            sb.Append(',');
            sb.Append(customer.Region);
            return sb.ToString();
        }) {
    }
}
CustomersComboBoxFilterInitial
      public override BolapanControl.ItemsFilter.Model.Filter NewFilter(BolapanControl.ItemsFilter.FilterPresenter filterPresenter, object key) {
            if (key != null && filterPresenter.CollectionView.SourceCollection is IEnumerable<Customer>) {
              return new CustomersComboBoxFilter();
          }
          return null;
      }
  }

Несмотря на краткость, это полный листинг создаваемых классов!

В шаблон элемента управления ComboBox вносим вновь созданный фильтр и привязываем его к ItemsSource:

CustomerComboBoxStyle.xaml
<Style x:Key="ComboBoxStyle" TargetType="{x:Type ComboBox}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ComboBox}">
                <Grid x:Name="MainGrid" >
                    ...
                                    <bsFilter:FilterControl Key="CustomerAnyFieldFilter"
                                                               ParentCollection="{TemplateBinding ItemsSource}">
                                        <bsFilter:FilterControl.Resources>
                                            <Style BasedOn="{StaticResource CustomerComboBox_StringFilterStyle}" TargetType="{x:Type bsFilter:StringFilterView}" />
                                        </bsFilter:FilterControl.Resources>
                                        <bsFilter:FilterControl.FilterInitializersManager>
                                            <bsFilter:FilterInitializersManager>
                                                <vm:CustomersComboBoxFilterInitializer />
                                            </bsFilter:FilterInitializersManager>
                                        </bsFilter:FilterControl.FilterInitializersManager>
                                    </bsFilter:FilterControl>
                   ...                                   
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Все! Осталось настраить отображение фильтра через стиль CustomerComboBox_StringFilterStyle.

How look.

Pic8

Немногим сложнее организация фильтра для коллекций, содержащих вложенные коллекции, таких как исходная модель для TreeView.

Last edited Nov 8, 2013 at 7:23 PM by Mishkin, version 3