Встановлення фільтра на OpenFileDialog, щоб дозволити типові формати зображень?


229

У мене є цей код, як я можу дозволити йому приймати всі типові формати зображень? PNG, JPEG, JPG, GIF?

Ось що я маю досі:

public void EncryptFile()
{            
    OpenFileDialog dialog = new OpenFileDialog();
    dialog.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
    dialog.InitialDirectory = @"C:\";
    dialog.Title = "Please select an image file to encrypt.";

    if (dialog.ShowDialog() == DialogResult.OK)
    {
        //Encrypt the selected file. I'll do this later. :)
    }             
}

Зверніть увагу, що для фільтра встановлено .txt файли. Я міг би змінити PNG, але що з інших типів?

Відповіді:


289

З документів , потрібний вам синтаксис фільтра:

Office Files|*.doc;*.xls;*.ppt

тобто розділіть кілька розширень крапкою з комою - таким чином, Image Files|*.jpg;*.jpeg;*.png;... .


179

Дотримуйтесь цієї схеми, якщо ви переглядаєте файли зображень:

dialog.Filter =  "Image files (*.jpg, *.jpeg, *.jpe, *.jfif, *.png) | *.jpg; *.jpeg; *.jpe; *.jfif; *.png";

6
Можливо, ви хочете позбутися пробілів перед символом труби та після неї, а також між напів-двокрапкою та зірочкою у фільтрувальній частині. Але добре, інакше.
vapcguy

Ви також можете згрупувати будь-який тип файлу таким чином. Приємно!
Альпер

74

Ось приклад пропозиції ImageCodecInfo (в VB):

   Imports System.Drawing.Imaging
        ...            

        Dim ofd as new OpenFileDialog()
        ofd.Filter = ""
        Dim codecs As ImageCodecInfo() = ImageCodecInfo.GetImageEncoders()
        Dim sep As String = String.Empty
        For Each c As ImageCodecInfo In codecs
            Dim codecName As String = c.CodecName.Substring(8).Replace("Codec", "Files").Trim()
            ofd.Filter = String.Format("{0}{1}{2} ({3})|{3}", ofd.Filter, sep, codecName, c.FilenameExtension)
            sep = "|"
        Next
        ofd.Filter = String.Format("{0}{1}{2} ({3})|{3}", ofd.Filter, sep, "All Files", "*.*")

І це виглядає приблизно так:

введіть тут опис зображення


Перевага цього підходу: він буде в курсі будь-яких майбутніх доповнень підтримуваних типів зображень до .NET. Спасибі
UuDdLrLrSs

Мені це дуже подобається, що я перетворив його на найбільш огидний однопластовий в світі! Dim ofd As New OpenFileDialog() With {.Filter = ImageCodecInfo.GetImageEncoders().Aggregate("All Files (*.*)|*.*", Function(s, c) $"{s}|{c.CodecName.Substring(8).Replace("Codec", "Files").Trim()} ({c.FilenameExtension})|{c.FilenameExtension}")}Ага, так. В.Б., іноді я сумую за тобою
Westonsupermare

46

Повне рішення в C # знаходиться тут:

private void btnSelectImage_Click(object sender, RoutedEventArgs e)
{
    // Configure open file dialog box 
    Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
    dlg.Filter = "";

    ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
    string sep = string.Empty;

    foreach (var c in codecs)
    {
       string codecName = c.CodecName.Substring(8).Replace("Codec", "Files").Trim();
       dlg.Filter = String.Format("{0}{1}{2} ({3})|{3}", dlg.Filter, sep, codecName, c.FilenameExtension);
       sep = "|";
    }

    dlg.Filter = String.Format("{0}{1}{2} ({3})|{3}", dlg.Filter, sep, "All Files", "*.*"); 

    dlg.DefaultExt = ".png"; // Default file extension 

    // Show open file dialog box 
    Nullable<bool> result = dlg.ShowDialog();

    // Process open file dialog box results 
    if (result == true)
    {
       // Open document 
       string fileName  = dlg.FileName;
       // Do something with fileName  
    }
} 

23

Для фільтрування файлів зображень використовуйте цей зразок коду.

//Create a new instance of openFileDialog
OpenFileDialog res = new OpenFileDialog();

//Filter
res.Filter = "Image Files|*.jpg;*.jpeg;*.png;*.gif;*.tif;...";

//When the user select the file
if (res.ShowDialog() == DialogResult.OK)
{
   //Get the file's path
   var filePath = res.FileName;
   //Do something
   ....
}

14

Найкраще мені подобається відповідь Тома Фауста. Ось версія C # для його рішення, але дещо спрощує речі.

var codecs = ImageCodecInfo.GetImageEncoders(); 
var codecFilter = "Image Files|"; 
foreach (var codec in codecs) 
{
    codecFilter += codec.FilenameExtension + ";"; 
} 
dialog.Filter = codecFilter;

11

Для зображень ви можете отримати доступні кодеки від GDI (System.Drawing) та створити свій список із цього, доклавши невеликої роботи. Це було б найбільш гнучким шляхом.

ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();

5
Дякую за цю пораду! Я додав їх, і це спрацювало як принадність: var imageExtensions = string.Join(";", ImageCodecInfo.GetImageDecoders().Select(ici => ici.FilenameExtension)); dialog.Filter = string.Format("Images|{0}|All Files|*.*", imageExtensions);
atlantis

тьфу ... не впевнений, як зробити багаторядкові блоки коду в коментарі: |
атлантис

1
Не оригінальний автор :)
atlantis

9

Просто некрокомент для використання string.Join та LINQ.

ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
dlgOpenMockImage.Filter = string.Format("{0}| All image files ({1})|{1}|All files|*", 
    string.Join("|", codecs.Select(codec => 
    string.Format("{0} ({1})|{1}", codec.CodecName, codec.FilenameExtension)).ToArray()),
    string.Join(";", codecs.Select(codec => codec.FilenameExtension).ToArray()));

4

Для тих, хто не хоче згадувати синтаксис кожного разу, тут проста пробка:

public class FileDialogFilter : List<string>
{
    public string Explanation { get; }

    public FileDialogFilter(string explanation, params string[] extensions)
    {
        Explanation = explanation;
        AddRange(extensions);
    }

    public string GetFileDialogRepresentation()
    {
        if (!this.Any())
        {
            throw new ArgumentException("No file extension is defined.");
        }

        StringBuilder builder = new StringBuilder();

        builder.Append(Explanation);

        builder.Append(" (");
        builder.Append(String.Join(", ", this));
        builder.Append(")");

        builder.Append("|");
        builder.Append(String.Join(";", this));

        return builder.ToString();
    }
}

public class FileDialogFilterCollection : List<FileDialogFilter>
{
    public string GetFileDialogRepresentation()
    {
        return String.Join("|", this.Select(filter => filter.GetFileDialogRepresentation()));
    }
}

Використання:

FileDialogFilter filterImage = new FileDialogFilter("Image Files", "*.jpeg", "*.bmp");
FileDialogFilter filterOffice = new FileDialogFilter("Office Files", "*.doc", "*.xls", "*.ppt");

FileDialogFilterCollection filters = new FileDialogFilterCollection
{
    filterImage,
    filterOffice
};

OpenFileDialog fileDialog = new OpenFileDialog
{
    Filter = filters.GetFileDialogRepresentation()
};

fileDialog.ShowDialog();

3

Щоб відповідати списку різних категорій файлів, ви можете використовувати такий фільтр:

        var dlg = new Microsoft.Win32.OpenFileDialog()
        {
            DefaultExt = ".xlsx",
            Filter = "Excel Files (*.xls, *.xlsx)|*.xls;*.xlsx|CSV Files (*.csv)|*.csv"
        };

1

Це надзвичайно, але я створив динамічний фільтр, керований базою даних, використовуючи таблицю баз даних 2 стовпців під назвою FILE_TYPES, з назвами полів EXTENSION та DOCTYPE:

---------------------------------
| EXTENSION  |  DOCTYPE         |
---------------------------------
|   .doc     |  Document        |
|   .docx    |  Document        |
|   .pdf     |  Document        |
|   ...      |  ...             |
|   .bmp     |  Image           |
|   .jpg     |  Image           |
|   ...      |  ...             |
---------------------------------

Очевидно, у мене було багато різних типів та розширень, але я спрощую це на цьому прикладі. Ось моя функція:

    private static string GetUploadFilter()
    {
        // Desired format:
        // "Document files (*.doc, *.docx, *.pdf)|*.doc;*.docx;*.pdf|"
        // "Image files (*.bmp, *.jpg)|*.bmp;*.jpg|"

        string filter = String.Empty;
        string nameFilter = String.Empty;
        string extFilter = String.Empty;

        // Used to get extensions
        DataTable dt = new DataTable();
        dt = DataLayer.Get_DataTable("SELECT * FROM FILE_TYPES ORDER BY EXTENSION");

        // Used to cycle through doctype groupings ("Images", "Documents", etc.)
        DataTable dtDocTypes = new DataTable();
        dtDocTypes = DataLayer.Get_DataTable("SELECT DISTINCT DOCTYPE FROM FILE_TYPES ORDER BY DOCTYPE");

        // For each doctype grouping...
        foreach (DataRow drDocType in dtDocTypes.Rows)
        {
            nameFilter = drDocType["DOCTYPE"].ToString() + " files (";

            // ... add its associated extensions
            foreach (DataRow dr in dt.Rows)
            {
                if (dr["DOCTYPE"].ToString() == drDocType["DOCTYPE"].ToString())
                {
                    nameFilter += "*" + dr["EXTENSION"].ToString() + ", ";
                    extFilter += "*" + dr["EXTENSION"].ToString() + ";";
                }                    
            }

            // Remove endings put in place in case there was another to add, and end them with pipe characters:
            nameFilter = nameFilter.TrimEnd(' ').TrimEnd(',');
            nameFilter += ")|";
            extFilter = extFilter.TrimEnd(';');
            extFilter += "|";

            // Add the name and its extensions to our main filter
            filter += nameFilter + extFilter;

            extFilter = ""; // clear it for next round; nameFilter will be reset to the next DOCTYPE on next pass
        }

        filter = filter.TrimEnd('|');
        return filter;
    }

    private void UploadFile(string fileType, object sender)
    {            
        Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
        string filter = GetUploadFilter();
        dlg.Filter = filter;

        if (dlg.ShowDialog().Value == true)
        {
            string fileName = dlg.FileName;

            System.IO.FileStream fs = System.IO.File.OpenRead(fileName);
            byte[] array = new byte[fs.Length];

            // This will give you just the filename
            fileName = fileName.Split('\\')[fileName.Split('\\').Length - 1];
            ...

Потрібно отримати фільтр, який виглядає приблизно так:

введіть тут опис зображення


Downvoter, хочете пояснити? Ви маєте кращу ідею? Шахта працює, як я продемонстрував за допомогою графіки.
vapcguy

2
Filter="Document files (*.doc,*.docx,*.pdf)|*.doc;*.docx,*.pdf|Image files (*.bmp,*.jpg)|*.bmp;*.jpg";і це має отримати фільтр, схожий на останнє зображення у відповіді вище.
mjb

@mjb Якщо ви подивилися на мою відповідь, то побачили б, що я вже це мав у коментарі вгорі коду. Якби це не спрацювало, я не мав би графіки, щоб довести, що це так. Як я пояснив, код приймає значення з таблиці бази даних і з'єднує їх. Ви просто поставите Doctype ("Документи", "Зображення" тощо) та розширення як 2 стовпчики на таблиці під назвою "FILE_TYPES". Якщо припустити, що у вас була функція, DataLayer.Get_DataTable()яка викликала команди SQL, які я маю в цьому коді, і надсилає вам назад DataTable, вона зробить все за вас. Як я вже говорив, так, це було надзвичайно, але це працює.
vapcguy

Так. але ем ... лише 10% вашої публікації - це пряма відповідь на питання. Інші 90% - це додаткова інформація, яка не потрібна для вирішення питання. Питання не вимагає інформації про отримання даних з бази даних і не запитувало про конкатенати ... і bla ... bla ... bla .... ще кілька команд SQL? ... DataTable? Чому ви також не включите витягування даних з веб-служб ... і не продемонструйте розбір рядків JSON .. або перетворення даних XML, щоб отримати типи файлів? а також від NoSQL? і виклик Javascript з переднього та заднього кінців для типів файлів? .... ні ... це поза темою.
mjb

@mjb Точка прийнята, але це також продемонструвати силу цього foreachциклу посередині. У вас можуть бути TONS різних доктів і розширень. Це послужило способом їх організації, а потім застосувати код, щоб отримати їх. Для мене це було краще, ніж просто припускати, що їх було лише 3 і давати рядок конкатенації. Навчіть людину ловити рибу ....
vapcguy
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.