C# 从数据绑定更新时,是否可以将筛选器自动应用于集合?

C# 从数据绑定更新时,是否可以将筛选器自动应用于集合?,c#,wpf,xaml,data-binding,collections,C#,Wpf,Xaml,Data Binding,Collections,简短的版本是:我是否需要手动刷新视图,以便将筛选器应用于具有数据绑定的集合,还是可以作为正常数据绑定过程的一部分进行刷新? 我有一个DataGrid,我正试图自动更新它。我想做的一件事是排除某些值设置为true的项目。下面是我用来实现这一点的代码。它是从不同的地方拼凑而成的,但它应该能让人明白这一点。这可能看起来像是一堵相当大的代码墙,但我已经尽力使代码片段尽可能小,同时保持我的意图清晰可辨 这是设置我应用于集合的筛选器的代码: CollectionView processView = (Col

简短的版本是:我是否需要手动刷新视图,以便将筛选器应用于具有数据绑定的集合,还是可以作为正常数据绑定过程的一部分进行刷新?

我有一个
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
接口,xaml中的数据触发器会拾取更改,集合本身会在添加或删除项时按预期进行更新。但是,如果我尝试在过滤器中启用触发排除的布尔值,它将不会隐藏,直到在视图上调用手动
Refresh()


是否有办法使其自动更新,或者是否需要通过手动刷新应用过滤器?

由于您使用的是MVVM,我建议将设置过滤器的代码移动到ViewModel中,如果IsScheduled属性也在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;
    }
}
公共类示例ViewModel:BaseViewModel
{
私有只读可观察收集项目;
私有只读ListCollectionView_filteredItems;
公共示例ViewModel()
{
_项目=新的RadobserveCollection();
_filteredItems=newlistcollectionview(_items){Filter=MyFilter};
//待办事项-填写项目。。。
}
公共IEnumerable项{get{return\u filteredItems;}}
公共图书馆已排定日程
{
获取{return isScheduled;}
设置
{
isScheduled=值;
NotifyPropertyChanged();
_filteredItems.Refresh();
}
}
私有布尔MyFilter(对象项)
{
ExampleChildViewModel thisItem=项目作为ExampleChildViewModel;
如果(thisItem==null)
{
返回false;
}
if(thisItem.Name==“AwkwardCoder”)
{
返回true;
}
返回false;
}
}

设置过滤器的代码在哪里?@AwkwardCoder过滤器设置在第一个代码部分。我在“使用”MVVM时对它有一个非常基本的了解,但我非常确定我现在设置它的方式是合格的。过滤代码在哪里执行-在视图的代码后面还是在ViewModel中?@AwkwardCoder过滤代码在代码后面和IsScheduled属性中,这在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;
    }
}