所以问题是,昨天我想制作一个用于过滤数据网格的搜索栏。我成功地做到了这一点但是当我今天看着它时,我意识到我不知道它为什么会起作用。以下是令我困惑的事情:
基本上我有一个datagrid,其ItemsSource设置为名为Equipments的ObservableCollection。为了过滤设备,我还创建了一个名为EquipmentView的ICollectionView,它只是我可以过滤的设备的镜像。
设备在我的数据库中的表中的viewmodel中填充,如下所示:
public async Task LoadAsync()
{
try
{
var lookup = await _equipmentLookupDataService.GetEquipmentLookupAsync();
Equipments.Clear();
foreach (var item in lookup)
{
Equipments.Add(item);
}
EquipmentView = CollectionViewSource.GetDefaultView(Equipments);
EquipmentView.Filter = new Predicate<object>(Filter);
}
catch (Exception e)
{
MessageBox.Show(e.Message, "An error occurred", MessageBoxButton.OK, MessageBoxImage.Warning);
//create new error object from the exception and add to DB
Error error = new Error
{
ErrorMessage = e.Message,
ErrorTimeStamp = DateTime.Now,
ErrorStackTrace = e.StackTrace,
LoginId = CurrentUser.LoginId
};
await _errorDataService.AddError(error);
}
}
EquipmentView.Filter调用Filter方法:
public bool Filter(object obj)
{
var data = obj as EquipmentLookup;
if (EquipmentView != null)
{
if (!string.IsNullOrEmpty(_filterString))
{
string allcaps = _filterString.ToUpper();
return data.TypeName.StartsWith(_filterString) || data.TypeName.StartsWith(allcaps);
}
return true;
}
return false;
}
仅当TypeName属性以filterstring开头时才返回true,filterstring是绑定到我的搜索栏的字符串。
现在我想到我只需要将datagrid ItemsSource设置为EquipmentView。如果我这样做,一切正常,数据网格只显示与搜索栏匹配的任何内容。
显然,如果我将datagrid上的itemsSource设置回到Equipments,它仍然有效,包括搜索栏。为什么是这样?据我所知,我对EquipmentView进行过滤不应该改变有关Equipments的任何内容,但无论如何它似乎都是这样做的。
一切都很好,我只是希望我知道为什么。
搜索栏的XAML代码:
<TextBox Name="SearchBar" Margin="10 10 10 10" Text="{Binding FilterString, UpdateSourceTrigger=PropertyChanged}"/>
的Datagrid:
<DataGrid MaxHeight="800"
ItemsSource="{Binding Equipments}"
SelectedItem="{Binding SelectedEquipment, Mode=TwoWay}"
IsReadOnly="True"
CanUserReorderColumns="False"
SelectionMode="Single"
ColumnWidth="*">
<DataGrid.ItemContainerStyle>
<Style TargetType="DataGridRow">
<EventSetter Event="MouseDoubleClick"
Handler="Row_DoubleClick" />
</Style>
</DataGrid.ItemContainerStyle>
</DataGrid>
答案 0 :(得分:3)
来自WPF文档:
所有集合都有默认的CollectionView。 WPF总是绑定到 查看而不是集合。如果直接绑定到集合, WPF实际上绑定到该集合的默认视图。这个 默认视图由集合的所有绑定共享,这会导致 所有直接绑定到集合以共享排序,过滤, 组和一个默认视图的当前项特征。
现在在您的代码中,您正在执行此操作:
EquipmentView = CollectionViewSource.GetDefaultView(Equipments);
EquipmentView.Filter = new Predicate<object>(Filter);