过滤列表视图未触发

时间:2017-10-06 16:53:12

标签: c# wpf list listview treeview

我正在尝试根据我的TextBox过滤我的ListView,但由于某种原因它没有被触发。运行调试器,我可以看到要更改的输入文本,但它没有反映在ListView中。

我的主视图模型:

        projectCollection = new CollectionViewSource();
        projectCollection.Source = Projects;
        projectCollection.Filter += projectCollection_Filter;
    }

    public ICollectionView SourceCollection
    {
        get
        {
            return this.projectCollection.View;
        }
    }

    public string FilterText
    {
        get
        {
            return filterText;
        }
        set
        {
            filterText = value;
            this.projectCollection.View.Refresh();
            RaisePropertyChanged("SearchProjectsText");
        }
    }

    private void projectCollection_Filter(object sender, FilterEventArgs e)
    {
        if (string.IsNullOrEmpty(FilterText))
        {
            e.Accepted = true;
            return;
        }

        Project project = e.Item as Project;
        if (project.Name.ToUpper().Contains(FilterText.ToUpper()) || project.Path.ToUpper().Contains(FilterText.ToUpper()))
        {
            e.Accepted = true;
        }
        else
        {
            e.Accepted = false;
        }
    }

    public void RaisePropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

}

我的相关XAML:

<TextBox x:Name="SearchProjectsBox" Grid.Column="5" Background="White" Grid.Row="1" Text="{Binding FilterText, UpdateSourceTrigger=PropertyChanged}"
        Margin="47.333,0,0,654.333" VerticalContentAlignment="Center" Foreground="Black" Padding="6" FontSize="16" HorizontalAlignment="Left" Width="268"/>

                <ListView x:Name="ProjectListView" Margin="0,0,10,0" ItemsSource="{Binding ElementName=Hierarchy, Path=SelectedItem.GetAllMembers, UpdateSourceTrigger=PropertyChanged}" FontSize="16" Foreground="Black">

编辑。这是XAML。

<TextBox x:Name="SearchProjectsBox" Grid.Column="5" Background="White" Grid.Row="1" Text="{Binding FilterText, UpdateSourceTrigger=PropertyChanged}"
        Margin="47.333,0,0,654.333" VerticalContentAlignment="Center" Foreground="Black" Padding="6" FontSize="16" HorizontalAlignment="Left" Width="268"/>
    <TreeView x:Name="Hierarchy" Grid.Column="4" HorizontalAlignment="Left" Height="631" Margin="0,58,0,0" Grid.Row="1" VerticalAlignment="Top" Width="226" 
              ItemsSource="{Binding Path=Projects}">
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding ChildFolders}">
                <StackPanel Orientation="Horizontal" >
                    <Image Source="{Binding Icon}" MouseUp="SelectedFolder_Event" Margin="5, 5, 5, 5"></Image>
                    <TextBox x:Name="FolderNames" Text="{Binding Name, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" BorderThickness="0" FontSize="16" Margin="5" IsReadOnly="True" PreviewMouseDoubleClick="SelectAll" LostFocus="TextBoxLostFocus"/>
                </StackPanel>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>

这是我的视图模型模板。

private ObservableCollection<Project> projects;
    private string filterText;
    private CollectionViewSource projectCollection;
    public event PropertyChangedEventHandler PropertyChanged;
    public ObservableCollection<Project> Projects
    {
        get { return projects; }
        set
        {
            if (value != projects)
            {
                projects = value;
                OnPropertyChanged("Projects");
            }
        }
    }

    public string FilterText
    {
        get
        {
            return filterText;
        }
        set
        {
            filterText = value;
            this.projectCollection.View.Refresh();
            OnPropertyChanged("SearchProjectsText");
        }
    }

    private void projectCollection_Filter(object sender, FilterEventArgs e)
    {
        if (string.IsNullOrEmpty(FilterText))
        {
            e.Accepted = true;
            return;
        }

        Project project = e.Item as Project;
        if (project.Name.ToUpper().Contains(FilterText.ToUpper()) || project.Path.ToUpper().Contains(FilterText.ToUpper()))
        {
            e.Accepted = true;
        }
        else
        {
            e.Accepted = false;
        }
    }

    public void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

上述方法是用于根据TextBox文本过滤和更新列表视图的方法。

1 个答案:

答案 0 :(得分:0)

在CollectionView中使用过滤器的简单示例。请参阅下面的代码。

<Grid >
    <StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Filter"/>
            <TextBox Text="{Binding TextValue, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Width="200"/>
        </StackPanel>
        <ListBox ItemsSource="{Binding EmpView}" DisplayMemberPath="Name"/>
    </StackPanel>

</Grid>

class ViewModel : INotifyPropertyChanged
{
    private string myVar;

    public string TextValue
    {
        get { return myVar; }
        set { myVar = value;
            OnPropertyChanged("TextValue"); EmpView.Refresh();}
    }

    public ICollectionView EmpView { get; set; }
    public List<Employee> Employees { get; set; }
    public ViewModel()
    {
        Employees = new List<Employee>()
        {
            new Employee() {Name = "Test1"},
            new Employee() {Name = "Version2"},
            new Employee() {Name = "Test2"},
            new Employee() {Name = "Version4"},
            new Employee() {Name = "Version5"}
        };
        EmpView = CollectionViewSource.GetDefaultView(Employees);
        EmpView.Filter = Filter;
    }

    private bool Filter(object emp)
    {
        if (string.IsNullOrWhiteSpace(TextValue))
        {
            return true;
        }
        var emp1 = emp as Employee;
        return TextValue != null && (emp1 != null && emp1.Name.Contains(TextValue));
    }


    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

class Employee
{
    public string Name { get; set; }
}