这个的简短版本是:我是否需要手动刷新视图,以便将过滤器应用于具有数据绑定的集合,还是可以将其作为常规数据绑定过程的一部分来完成?
我有DataGrid
我想要自动更新。我要做的其中一件事是将具有特定值设置为true
的项排除。以下是我用来实现此目的的代码。它从各个地方拼凑而成,但它应该得到重点。它可能看起来像是一个相当大的代码墙,但我试图尽可能地保持小片段,同时保持我的意图可识别。
这是设置我正在应用于集合的过滤器的代码:
CollectionView processView = (CollectionView)CollectionViewSource.GetDefaultView(ProcessBox.ItemsSource);
processView.Filter = ProcessFilter;
// Elsewhere
private bool ProcessFilter(object item)
{
ProcessContainer thisItem = item as ProcessContainer;
if (thisItem.IsScheduled == true)
return false;
if (String.IsNullOrEmpty(FilterInput.Text))
{
return true;
}
else
{
return (thisItem.ProcessName.IndexOf(FilterInput.Text, StringComparison.OrdinalIgnoreCase) >= 0);
}
}
在路上,我有一个输入,允许用户按文本过滤列表。此有效,但它使用手动更新。
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
CollectionViewSource.GetDefaultView(ProcessBox.ItemsSource).Refresh();
}
以下是datagrid的xaml:
<DataGrid x:Name="ProcessBox" SelectionMode="Extended" ScrollViewer.HorizontalScrollBarVisibility="Hidden" GridLinesVisibility="None" AutoGenerateColumns="False" IsReadOnly="True" Margin="0,0,0,33" CanUserReorderColumns="False" MinColumnWidth="50" CanUserResizeRows="False">
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Style.Triggers>
<DataTrigger Binding="{Binding IsScheduled}" Value="true">
<Setter Property="Foreground" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="Process" Binding="{Binding ProcessName}" />
<DataGridTextColumn Header="Memory" Binding="{Binding Memory}" />
</DataGrid.Columns>
</DataGrid>
我有红色文本触发器,以确保它们都被绑定并正确设置。我的模型实现INotifyPropertyChanged
,列表上的颜色将在布尔值更改时自动更新颜色。也就是说,当我设置布尔值时,运行:
public bool IsScheduled
{
get { return isScheduled; }
set { isScheduled = value; NotifyPropertyChanged(); }
}
...颜色会按预期变化,但过滤器不会运行。
我正在使用自己的代码过滤ObservableCollection<T>
,当我手动更新它时它会起作用。我的模型实现了INotifyPropertyChanged
接口,xaml中的数据触发器获取了更改,并且在添加或删除项目时,集合本身会按预期更新。但是,如果我尝试启用在过滤器中触发排除的布尔值,则在视图上调用手动Refresh()
之前不会隐藏它。
有没有办法让它自动更新,还是需要通过手动刷新来应用过滤器?
答案 0 :(得分:0)
由于您正在使用MVVM,我建议将设置过滤器的代码移动到ViewModel中,如果IsMcheduled属性也在ViewModel上公开,那么很容易触发过滤器的刷新,可能是某些东西像这样:
public class ExampleViewModel : BaseViewModel
{
private readonly ObservableCollection<ExampleChildViewModel> _items;
private readonly ListCollectionView _filteredItems;
public ExampleViewModel()
{
_items = new RadObservableCollection<ExampleChildViewModel>();
_filteredItems = new ListCollectionView(_items) {Filter = MyFilter};
// todo - fill the items...
}
public IEnumerable Items { get { return _filteredItems; } }
public bool IsScheduled
{
get { return isScheduled; }
set
{
isScheduled = value;
NotifyPropertyChanged();
_filteredItems.Refresh();
}
}
private bool MyFilter(object item)
{
ExampleChildViewModel thisItem = item as ExampleChildViewModel;
if (thisItem == null)
{
return false;
}
if (thisItem.Name == "AwkwardCoder")
{
return true;
}
return false;
}
}