Dynamically adding .EndsWith() from combobox

Viewed 84

I have a combo box called comboFileTypes. Inside that is a drop down list containing:

MP4
MOV
MKV
VOB

And after a button press I have the following code to scan a directory for files:

var files = Directory
    .EnumerateFiles(sourceDIR.Text, "*.*", SearchOption.AllDirectories)
    .Where(s => 
        s.EndsWith(".mp4") || 
        s.EndsWith(".mov") || 
        s.EndsWith(".vob") ||
        s.EndsWith(".MP4") || 
        s.EndsWith(".MOV") || 
        s.EndsWith(".VOB"));

Which is hardcoded. I want the WHERE option to be dynamically generated from the combobox instead, so that the user can add another type of file if they need to. (Also case insensitive, if that's possible, otherwise I'll just add both cases)

Any help would be appreciated.

5 Answers

You can get values from ComboBox by

var values = comboFileTypes.Items.Cast<string>()

and use it in like this:

var files = Directory
    .EnumerateFiles(sourceDIR.Text, "*.*", SearchOption.AllDirectories)
    .Where(s => values.Any(v => s.EndsWith(v, StringComparison.OrdinalIgnorecase));

Well, maybe I'm missing something big, but...

void onOpen()
{
    var selected = comobFileTypes.SelectedItem;

    if ( selected != null ) {
        string ext = "." + selected.ToString();

        var files = Directory.EnumerateFiles(sourceDIR.Text, "*.*", SearchOption.AllDirectories).Where(
                s => s.EndsWith( ext );

        // ...more things...
    }

    return;
}

The key here is that ComboBox has a SelectedItem property, which can be null if nothing is selected, or hold the selected option.

If you want to select all the extensions, then you can use the Items property.

void onOpen()
{
    string[] items = new string[ comboFileTypes.Items.Length ];

    foreach(int i = 0; i < items.Length; ++i) {
        items[ i ] = "." + comboFileTypes.Items[ i ].ToString();
    }

    var files = new List<string>();
    var allFiles = Directory.EnumerateFiles( sourceDIR.Text, "*.*", SearchOption.AllDirectories );

    foreach(string ext in items) {
        files.AddRange( allFiles.Where( s => s.EndsWith( ext ) );
    }

    // ...more things... with files...
    return;
}

Hope this helps.

Get all extensions from combobox:

 var extensions = comboFileTypes.Items.Cast<string>().Select(x => "." + x);

Search ignoring case by enumerating all files in directory:

var files = Directory.EnumerateFiles(sourceDIR.Text, "*.*", SearchOption.AllDirectories).Where(x => extensions.Any(y => y.Equals(Path.GetExtension(x), StringComparison.OrdinalIgnoreCase)));

As alternative you could search for specified extensions only:

 var files = extensions.AsParallel().SelectMany(x => Directory.EnumerateFiles(sourceDIR.Text, "*" + x, SearchOption.AllDirectories));

try this code:

List<string> items = new List<string>();
for (int i = 0; i < comboBox1.Items.Count; i++)
{
    items.Add(comboBox1.Items[i].ToString().ToLower());
}

var files = Directory
        .EnumerateFiles(sourceDIR.Text, "*.*", SearchOption.AllDirectories)
        .Where(file => items.Any(item => file.ToLower().EndsWith(item)));

another possibility, would be to use the search pattern. Unfortunately it is not possible to search for multiple patterns at once. But you could use SelectMany to scan through the pattern list and flatten the search results into a single list:

var allPatterns = comboFileTypes.Items.Cast<string>();
allPatterns.SelectMany(pattern => Directory.EnumerateFiles(@"F:\temp", $"*.{pattern}", SearchOption.AllDirectories));

The filenames will be ordered as the pattern list

Related