Mengatur filter ke OpenFileDialog untuk memungkinkan format gambar khas?

229

Saya memiliki kode ini, bagaimana saya bisa mengizinkannya menerima semua format gambar khas? PNG, JPEG, JPG, GIF?

Inilah yang saya miliki sejauh ini:

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. :)
    }             
}

Perhatikan bahwa filter diatur ke file .txt. Saya bisa berubah menjadi PNG, tetapi bagaimana dengan tipe lainnya?

Sergio Tapia
sumber

Jawaban:

289

Dari dokumen , sintaksis filter yang Anda butuhkan adalah sebagai berikut:

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

yaitu, pisahkan beberapa ekstensi dengan tanda titik koma - dengan demikian Image Files|*.jpg;*.jpeg;*.png;...,.

itowlson
sumber
179

Ikuti pola ini jika Anda menjelajahi file gambar:

dialog.Filter =  "Image files (*.jpg, *.jpeg, *.jpe, *.jfif, *.png) | *.jpg; *.jpeg; *.jpe; *.jfif; *.png";
Devam Mehta
sumber
6
Mungkin ingin menyingkirkan spasi sebelum dan sesudah karakter pipa dan antara titik koma dan tanda bintang di bagian filter. Tapi bagus, sebaliknya.
vapcguy
Anda juga dapat mengelompokkan jenis file apa pun dengan cara ini. Bagus!
Alper
74

Berikut adalah contoh saran ImageCodecInfo (dalam 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", "*.*")

Dan terlihat seperti ini:

masukkan deskripsi gambar di sini

Tom Faust
sumber
Manfaat dari pendekatan ini: ini akan mengikuti penambahan jenis gambar yang didukung di masa depan untuk .NET. Terima kasih
UuDdLrLrSs
Saya sangat menyukai ini sehingga saya mengubahnya menjadi one-liner paling menjijikkan di dunia! 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}")}Ah iya. VB, aku terkadang merindukanmu
Westonsupermare
46

Solusi lengkap dalam C # ada di sini:

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  
    }
} 
Pengembang
sumber
23

Untuk memfilter file gambar, gunakan contoh kode ini.

//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
   ....
}
HermF
sumber
14

Saya suka jawaban Tom Faust yang terbaik. Ini adalah versi C # dari solusinya, tetapi menyederhanakan banyak hal.

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

Untuk gambar, Anda bisa mendapatkan codec yang tersedia dari GDI (System.Drawing) dan membuat daftar dari itu dengan sedikit kerja. Ini akan menjadi cara yang paling fleksibel untuk dilakukan.

ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
Muad'Dib
sumber
5
Terima kasih atas tip ini! Saya menambahkan ini dan itu bekerja seperti pesona: var imageExtensions = string.Join(";", ImageCodecInfo.GetImageDecoders().Select(ici => ici.FilenameExtension)); dialog.Filter = string.Format("Images|{0}|All Files|*.*", imageExtensions);
atlantis
ugh ... tidak yakin bagaimana melakukan blok kode multi-line dalam komentar: |
atlantis
1
Bukan penulis asli :)
atlantis
9

Hanya perlu untuk menggunakan string.Join dan 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()));
Anthony L. Gershman
sumber
4

Bagi mereka yang tidak ingin mengingat sintaks setiap kali di sini adalah enkapsulasi sederhana:

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()));
    }
}

Pemakaian:

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();
Yusuf Tarık Günaydın
sumber
3

Untuk mencocokkan daftar kategori file yang berbeda, Anda dapat menggunakan filter seperti ini:

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

Ini ekstrem, tetapi saya membangun filter dinamis yang digerakkan oleh database menggunakan tabel database 2 kolom bernama FILE_TYPES, dengan nama bidang EXTENSION dan DOCTYPE:

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

Jelas saya memiliki banyak jenis dan ekstensi yang berbeda, tetapi saya menyederhanakannya untuk contoh ini. Inilah fungsi saya:

    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];
            ...

Haruskah menghasilkan filter yang terlihat seperti ini:

masukkan deskripsi gambar di sini

vapcguy
sumber
Downvoter, mau jelaskan? Anda punya ide yang lebih baik? Milik saya berhasil, seperti yang saya tunjukkan melalui grafik.
vapcguy
2
Filter="Document files (*.doc,*.docx,*.pdf)|*.doc;*.docx,*.pdf|Image files (*.bmp,*.jpg)|*.bmp;*.jpg";dan ini akan menghasilkan filter yang terlihat seperti gambar terakhir dalam jawaban di atas.
mjb
@ mjb Jika Anda melihat jawaban saya, Anda akan melihat bahwa saya sudah memilikinya di komentar di bagian atas kode. Jika tidak berhasil, saya tidak akan memiliki grafik untuk membuktikannya. Seperti yang saya jelaskan, kode mengambil nilai dari tabel database & menggabungkannya. Anda cukup meletakkan Doctype ("Documents", "Images", dll.) Dan Extension sebagai 2 kolom pada tabel yang disebut "FILE_TYPES". Dengan asumsi Anda memiliki fungsi yang disebut DataLayer.Get_DataTable()yang akan mengambil perintah SQL yang saya miliki dalam kode ini & mengirim Anda kembali DataTable, itu akan melakukan segalanya untuk Anda. Seperti yang saya katakan, ya, itu ekstrem, tetapi itu berhasil.
vapcguy
Iya. tetapi em ... hanya 10% dari posting Anda yang merupakan jawaban langsung untuk pertanyaan itu. 90% lainnya adalah informasi tambahan yang tidak diperlukan untuk menyelesaikan pertanyaan. Pertanyaannya tidak meminta informasi tentang mendapatkan data dari database dan tidak bertanya tentang gabungan ... dan bla ... bla ... bla .... beberapa perintah SQL lagi? ... Tabel data? Mengapa Anda tidak menyertakan menarik data dari Layanan Web ... dan mendemonstrasikan penguraian string JSON .. atau konversi data XML untuk mendapatkan Jenis File? dan juga dari NoSQL? dan panggilan Javascript dari ujung depan ke ujung belakang untuk Jenis File? .... tidak ... yang keluar dari topik.
mjb
@ mjb Point diambil, tetapi juga untuk menunjukkan kekuatan foreachloop itu di tengah. Anda mungkin memiliki BANYAK dokumen yang berbeda, dan ekstensi di dalamnya. Ini berfungsi sebagai cara untuk mengaturnya, kemudian menerapkan kode untuk mendapatkannya. Bagi saya, itu lebih baik daripada hanya mengasumsikan hanya ada masing-masing 3 dan memberikan string gabungan. Ajari pria memancing ....
vapcguy