#c# #wpf #datagrid
Вопрос:
Я новичок в WPF и столкнулся с проблемой. У меня есть приложение MVVM WPF, и я хочу внедрить фильтрацию в свою сетку данных. Я перепробовал все возможные решения в Интернете, но по какой-то причине ни одно из них мне не подходит. Я создал текстовое поле и привязал его к FilterName
. То, что я хочу, чтобы это делалось при каждом нажатии клавиши, значение FilterName
должно обновляться и должен срабатывать фильтр. К сожалению, фильтр срабатывает только один раз — когда я запускаю приложение и помещаю точку останова в Set
блок FilterName
, я обнаружил, что она никогда его не достигает. Вот объявление текстового поля:
<TextBox
x:Name="FilterName"
MinWidth="150"
Margin="{StaticResource SmallTopBottomMargin}"
Background="Transparent"
BorderThickness="0,0,0,1"
Text="{Binding FilterName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, IsAsync=True}"
TextWrapping="Wrap" />
А вот и модель представления:
private readonly ObservableCollection<PersonData> _data;
public ICollectionView DataCollectionView { get; }
private string _filterName = string.Empty;
public string FilterName
{
get
{
return _filterName;
}
set
{
_filterName = value;
DataCollectionView.Refresh();
}
}
public MainWindowViewModel(ISampleDataService sampleDataService)
{
//Adding the data here
DataCollectionView = CollectionViewSource.GetDefaultView(_data);
DataCollectionView.Filter = FilterByName;
}
private bool FilterByName(object obj)
{
if (obj is PersonData data)
{
return data.Name.Contains(FilterName, StringComparison.InvariantCultureIgnoreCase);
}
return false;
}
Комментарии:
1. Похоже, что ваша проблема на самом деле просто проблема привязки, никак не связанная с фильтрацией и сеткой данных, верно? Вы уверены, что у вас есть модель просмотра, о которой вы думаете?
2. Да, я считаю, что все правильно, но данные не привязаны. Я попытался установить _filterName на «fi» при его объявлении (имена в _data «первый» и «второй»), и он правильно фильтрует сетку данных, но ничего не происходит, когда я пытаюсь отфильтровать ее с помощью текстового поля.
Ответ №1:
Эта привязка должна работать при условии, что модель представления со FilterName
свойством относится DataContext
к родительскому окну:
Text="{Binding DataContext.FilterName, UpdateSourceTrigger=PropertyChanged,
RelativeSource={RelativeSource AncestorType=Window}}"
Ответ №2:
- Установите имя вашего окна на
x:Name="_this"
и изменитеTextBox
привязку:
<TextBox
x:Name="tbFilterName"
DataContext="{Binding ElementName=_this}"
Text="{Binding Path=FilterName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
TextChanged="FilterName_TextChanged"
...
- Удалите
DataCollectionView.Refresh();
вызов изFilterName
сеттера, но добавьте
private void FilterName_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
DataCollectionView.Refresh();
}