views:

28

answers:

1

I am trying to display filenames in a listbox, retrieved from a particular directory. They are stored in an ObservableCollection of FileInfo objects:

public ObservableCollection<FileInfo> ProjectFiles
{
    get
    {
        if (SelectedFolder == null) return null;

        DirectoryInfo d= new DirectoryInfo(SelectedFolder);

        if (!d.Exists) return null;

        return new ObservableCollection<FileInfo>(d.EnumerateFiles("*.xsi"));
    }
}

I have implemented a filter on the listbox, called when text is entered or changed in a textbox "FilesFilterBy":

private void FilterFiles_TextChanged(object sender, TextChangedEventArgs e)
{
    ICollectionView view = CollectionViewSource.GetDefaultView(ProjectFiles);
    view.Filter = new Predicate<object>(IsTextInFilename);
}

public bool IsTextInFilename(object item)
{
    string Filename = Path.GetFileNameWithoutExtension((item as FileInfo).Name);
    return (Filename.ToLower().Contains(FilesFilterBy.Text.ToLower()));
}

At the same time, I want to display only the names of the files, without path or extension. To this end I have implemented a converter:

public class RemoveExtensionConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
    return Path.GetFileNameWithoutExtension(value as string);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return new NotImplementedException();
    }
}

Here is how the listbox is implemented in XAML:

<Window.Resources>
    <ctr:RemoveExtensionConverter x:Key="JustFileName" />
</Window.Resources>

<ListBox ItemsSource="{Binding ProjectFiles}" >
  <ListBox.ItemTemplate>
    <DataTemplate>
        <TextBlock Text="{Binding FullName, Converter={StaticResource JustFileName}}" />
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

Currently the converter works - only the file names are listed, but the filter no longer has any effect. When I enter text in the FileFilterBy textbox the TextChanged event is fired but the listbox stays the same. Also, the converter is not called at that point.

What am I doing wrong?

+2  A: 

ProjectFiles returns a new collection every time. Your FilterFiles_TextChanged handler is calling ProjectFiles to create a new collection, setting a filter on that new collection, and then throwing it away. The collection bound to the ListBox is not affected. You need to change ProjectFiles to keep the same collection object. Maybe something like this:

private ObservableCollection<FileInfo> _projectFiles;
public ObservableCollection<FileInfo> ProjectFiles
{
    get
    {
        if (_projectFiles == null)
        {
            if (SelectedFolder == null) return null;

            DirectoryInfo d = new DirectoryInfo(SelectedFolder);

            if (!d.Exists) return null;

            _projectFiles = new ObservableCollection<FileInfo>(
                d.EnumerateFiles("*.xsi"));
        }
        return _projectFiles;
    }
}

The Converter shouldn't affect the filter at all.

Quartermeister
Thank you kindly.
Michael Sandler