У меня есть gridview в списке. Существует столбец «Отдел», который привязан к свойству «Отдел» в модели, а также связан с преобразователем.
Преобразователь принимает значение, полученное от свойства, и отображает его в другой форме (с другой строкой).
Например, если это свойство "Отдел" имеет значение "100AB" в столбце отображается как "Финансовый", если значение доходит до "200CB" в столбце отображается "Администрация" и так далее...
Моя проблема заключается в фильтрации списка с помощью фильтра. Внутренне он фильтрует по «100AB», «200CB» вместо отображаемых значений «Финансы» и «Администрирование», так как это решить?
Просмотр (xaml):
<ListView Grid.Row="1" Grid.Column="0"
Name="MyListView"
ItemsSource="{Binding Path=View}"
<GridViewColumn Header="Department" Width="190"
DisplayMemberBinding="{Binding Department, Converter={StaticResource DeptTypeConverter}}">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock TextAlignment="Right"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
Конвертер:
public class DeptTypeConverter: IValueConverter
{
#region Constants
private const string DeptFinancialType = "100AB";
private const string DeptAdminType = "200CB";
private const string DeptFinancialView = "Finanacial";
private const string DeptAdminView = "Administration";
#endregion
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
// Do the conversion from drink type to present it in the view
string s = (string)value;
if (s == DeptFinancialType )
return DeptFinancialView;
else if (s == DeptAdminType)
return DeptAdminView;
else
throw new Exception(string.Format("Cannot convert, unknown value {0}", value));
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
// Do the conversion from presentation to data type
string s = (string)value;
if (s.Equals(DeptFinancialView, StringComparison.InvariantCultureIgnoreCase))
return DeptFinancialType;
else if (s.Equals(DeptAdminView, StringComparison.InvariantCultureIgnoreCase))
return DeptAdminType;
else
throw new Exception(string.Format("Cannot convert, unknown value {0}", value));
}
}
Фильтр в модели просмотра:
private CollectionView view;
public CollectionView View
{
get
{
return this.view;
}
private set
{
if (this.view == value)
{
return;
}
this.view = value;
OnPropertyChanged("View");
}
}
// This code in constructor
this.View = (CollectionView)CollectionViewSource.GetDefaultView(this.MyListView);
this.View.Filter = UserFilter;
//
private bool MyFilter(object item)
{
if (String.IsNullOrEmpty(this.TextToFilter))
{
return true;
}
else
{
DataModel m = (item as DataModel);
bool result = (m.Department.IndexOf(this.TextToFilter, StringComparison.OrdinalIgnoreCase) >= 0);
return result;
}
}
У меня есть другие поля в фильтре, по которым я фильтрую, но для простоты я не указал в методе MyFilter. В этих полях не используется конвертер, в данном случае он не нужен, нужен только в случае, который я предоставил.
DataModel — это модель данных, содержащая свойство «Отдел», к которому привязано представление.
this.TextToFilter — это текстовое поле в представлении для фильтрации.
ПОПЫТКА №1:
Вместо использования ConvertBack в DeptTypeConverter я использовал Convert (нет необходимости что-либо изменять в методе Convert). Ниже работает правильно.
private bool MyFilter(object item)
{
if (String.IsNullOrEmpty(this.TextToFilter))
{
return true;
}
else
{
DataModel m = (item as DataModel);
bool result = (new Converters.DeptTypeConverter().Convert(m.Department, null, null, null).ToString().IndexOf(this.TextToFilter, StringComparison.OrdinalIgnoreCase) >= 0);
return result;
}
}
m.Department содержит внутреннее сохраненное значение (не отображаемое).
Я думаю, что лучше использовать Convert, а не ConvertBack, поскольку пользователь вводит отображаемый текст (без значения, хранящегося внутри) при поиске. Использование ConvertBack требует большей логики для реализации, и это не так просто, как использование простого Convert.
Если у кого-то есть другие идеи получше, поделитесь. Любая идея или улучшения всегда приветствуются. Насколько это возможно, я хотел бы не нарушать архитектуру шаблона MVVM.