我有一个文本框和一个DataGrid。当我在文本框中输入内容时,我想过滤DataGrid中的数据。
我使用下面提到的代码完成了这个:
在XAML中:
<CollectionViewSource x:Key="GroupsViewSource" Source="{Binding Groups, UpdateSourceTrigger=PropertyChanged}" Filter="CollectionViewSource_Filter">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="GroupName"/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
<DataGrid Grid.Row="5" Grid.Column="1" ItemsSource="{Binding Source={StaticResource GroupsViewSource}}"
SelectedItem="{Binding SelectedGroup}"
AutoGenerateColumns="False" CanUserAddRows="False"
SelectionMode="Single" SelectionUnit="FullRow"
EnableRowVirtualization="False" VirtualizingPanel.IsContainerVirtualizable="False" RowEditEnding="DataGrid_RowEditEnding">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Group Name" Width="*" SortMemberPath="GroupName">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding GroupName}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<TextBox Text="{Binding GroupName}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Parent Group" Width="*" SortMemberPath="ParentID">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding ParentID, Converter={StaticResource parentIDToGroupNameConverter}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Source={StaticResource ParentGroupsViewSource}}"
DisplayMemberPath="GroupName"
SelectedValue="{Binding ParentID, Converter={StaticResource parentIDToGroupNameConverter}}" SelectedValuePath="GroupName"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Edit" Width="50" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Button x:Name="btnEdit" Style="{StaticResource ResourceKey=EditButton}" Height="35" Width="35"
Visibility="{Binding DataContext.IsInEdit,
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}},
Converter={StaticResource boolToVisibilityInverseConverter}}"
Click="EditSaveButton_Click"
Command="{Binding DataContext.EditCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}"/>
<Button x:Name="btnSave" Grid.Row="1" Style="{StaticResource ResourceKey=SaveButton}" Height="35" Width="35"
Visibility="{Binding DataContext.IsInEdit,
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}},
Converter={StaticResource boolToVisibilityConverter}}"
Click="EditSaveButton_Click"
Command="{Binding DataContext.SaveCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Delete" Width="70" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Button x:Name="btnDelete" Style="{StaticResource ResourceKey=DeleteButton}" Height="35" Width="35"
Visibility="{Binding DataContext.IsInEdit,
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}},
Converter={StaticResource boolToVisibilityInverseConverter}}"
Command="{Binding DataContext.DeleteCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}"/>
<Button x:Name="btnCancel" Grid.Row="1" Style="{StaticResource ResourceKey=CancelButton}" Height="35" Width="35"
Visibility="{Binding DataContext.IsInEdit,
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}},
Converter={StaticResource boolToVisibilityConverter}}"
Command="{Binding DataContext.CancelCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<TextBox Grid.Column="0" Text="{Binding SearchGroupName, UpdateSourceTrigger=PropertyChanged}" />
在CodeBehind中:
private void CollectionViewSource_Filter(object sender, FilterEventArgs e)
{
var a = e.Item.GetType().GetProperty("GroupName");
if (a != null)
{
if (_viewModel.SearchGroupName != "")
{
var s = a.GetValue(e.Item, null);
if (s != null)
e.Accepted = s.ToString().Contains(_viewModel.SearchGroupName, StringComparison.OrdinalIgnoreCase);
else
e.Accepted = false;
}
else
e.Accepted = true;
}
}
在ViewModel中:
ERPLiteDBContext db = new ERPLiteDBContext();
public ListViewModel()
{
Groups = new ObservableCollection<Group>(db.Groups);
SearchGroupName = "";
}
private string _searchGroupName;
public string SearchGroupName
{
get
{
return _searchGroupName;
}
set
{
_searchGroupName = value;
OnPropertyChanged("SearchGroupName");
}
}
private ObservableCollection<Group> _groups;
public ObservableCollection<Group> Groups
{
get
{
return _groups;
}
set
{
_groups = value;
OnPropertyChanged("Groups");
}
}
以上代码有效。但是要使上面的代码工作,我必须在textBox中键入内容,然后单击DataGrid的标题对其进行排序。因此,简而言之,上面的代码不提供实时过滤。当我在TextBox中键入内容时,我想过滤我的数据......
答案 0 :(得分:1)
因此,代码中的过滤实际上是排序的后续操作。要随时执行过滤,我建议您关注,对视图模型进行少量更改:
Group
知道是否应该过滤本身。它有IsHidden
属性:
public class Group // actually a viewmodel
{
public bool IsHidden
{
get;
set;
}
public string Name
{
get;
set;
}
...
}
每次Text更改时,都会为集合中的每个成员设置 IsHidden
。 CollectionViewSource
检查此属性:
private void OnTextBoxTextChanged(object sender, TextChangedEventArgs e)
{
// reset first to keep continious filtering
Groups.ToList().ForEach(i => i.IsHidden = false);
foreach (var filteredGroup in Groups.Where(vm => vm.Name == _viewModel.SearchGroupName))
{
filteredGroup.IsHidden = true;
}
ICollectionView cv = CollectionViewSource.GetDefaultView(_dataGrid.ItemsSource);
if (cv != null)
{
// filter the Groups collection
cv.Filter = (vm as Group) => vm.IsHidden == false;
}
}