ตั้งค่าตัวกรองเป็น 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

คุณยังสามารถจัดกลุ่มไฟล์ประเภทใดก็ได้ด้วยวิธีนี้ ดี!
Alper

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}")}อ่าใช่ VB, บางครั้งฉันคิดถึงคุณ
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

ฉันชอบคำตอบที่ดีที่สุดของ Tom Faust นี่เป็นวิธีแก้ปัญหาของเขาในเวอร์ชัน 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

อืม ... ไม่แน่ใจว่าจะทำบล็อคโค้ดหลายบรรทัดได้อย่างไรในความคิดเห็น: |
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 ("Documents", "Images" และอื่น ๆ ) และส่วนขยายเป็น 2 คอลัมน์บนตารางชื่อ "FILE_TYPES" สมมติว่าคุณมีฟังก์ชั่นที่เรียกDataLayer.Get_DataTable()ว่าใช้คำสั่ง SQL ที่ฉันมีในรหัสนี้และส่ง DataTable กลับมาคุณจะทำทุกอย่างให้คุณ อย่างที่ฉันบอกว่าใช่รุนแรงมาก แต่ก็ใช้ได้
vapcguy

ใช่. แต่ em ... เพียง 10% ของโพสต์ของคุณคือคำตอบที่ตรงกับคำถาม อีก 90% เป็นข้อมูลเพิ่มเติมซึ่งไม่จำเป็นต้องแก้ปัญหา คำถามไม่ได้ขอข้อมูลเกี่ยวกับการรับข้อมูลจากฐานข้อมูลและไม่ได้ถามเกี่ยวกับการเชื่อมต่อ ... และ bla ... bla ... bla ... bla .... บางคำสั่ง SQL เพิ่มเติมหรือไม่ ... ตารางข้อมูล? ทำไมคุณไม่รวมถึงการดึงข้อมูลจากบริการบนเว็บ ... และสาธิตการแยกสตริง JSON .. หรือการแปลงข้อมูล XML เพื่อรับประเภทไฟล์ และจาก NoSQL? และ Javascript โทรจาก front end to back end สำหรับประเภทไฟล์? .... ไม่ ... ที่อยู่นอกหัวข้อ
mjb

@mjb จุดที่นำมา แต่ก็ยังแสดงให้เห็นถึงพลังของforeachวงที่อยู่ตรงกลาง คุณอาจมีหลักคำสอนที่แตกต่างกันมากมายและส่วนขยายภายใน สิ่งนี้ทำหน้าที่เป็นวิธีการจัดระเบียบพวกเขาจากนั้นใช้รหัสเพื่อรับพวกเขา สำหรับฉันมันดีกว่าแค่สมมติว่ามีเพียง 3 อันเท่านั้นและให้สตริงการต่อข้อมูล สอนคนตกปลา ....
vapcguy
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.