Đặt bộ lọc thành OpenFileDialog để cho phép các định dạng hình ảnh điển hình?


229

Tôi có mã này, làm cách nào tôi có thể cho phép nó chấp nhận tất cả các định dạng hình ảnh điển hình? PNG, JPEG, JPG, GIF?

Đây là những gì tôi có cho đến nay:

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

Lưu ý rằng bộ lọc được đặt thành tệp .txt. Tôi có thể thay đổi thành PNG, nhưng các loại khác thì sao?

Câu trả lời:


289

Từ các tài liệu , cú pháp bộ lọc mà bạn cần như sau:

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

tức là tách nhiều phần mở rộng bằng dấu chấm phẩy - do đó , Image Files|*.jpg;*.jpeg;*.png;....


179

Thực hiện theo mẫu này nếu bạn duyệt tìm tệp hình ảnh:

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

6
Có lẽ muốn thoát khỏi khoảng trắng trước và sau ký tự ống và giữa dấu chấm phẩy và dấu hoa thị trong phần bộ lọc. Nhưng tốt, nếu không.
vapcguy

Bạn cũng có thể nhóm bất kỳ loại tệp theo cách này. Đẹp!
Alper

74

Đây là một ví dụ về đề xuất ImageCodecInfo (bằng 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", "*.*")

Và nó trông như thế này:

nhập mô tả hình ảnh ở đây


Lợi ích của phương pháp này: nó sẽ theo kịp với bất kỳ bổ sung nào trong tương lai của các loại hình ảnh được hỗ trợ cho .NET. Cảm ơn
UuDdLrLrSs

Tôi yêu nó rất nhiều đến nỗi tôi đã chuyển đổi nó thành một lớp lót kinh tởm nhất thế giới! 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}")}À, vâng. VB, đôi khi tôi nhớ bạn
Westonsupermare

46

Giải pháp hoàn chỉnh trong C # có tại đây:

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

Để lọc tập tin hình ảnh, sử dụng mẫu mã này.

//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

Tôi thích câu trả lời của Tom Faust nhất. Đây là phiên bản C # của giải pháp của anh ấy, nhưng đơn giản hóa mọi thứ một chút.

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

11

Đối với hình ảnh, bạn có thể lấy các codec có sẵn từ GDI (System.Drawing) và xây dựng danh sách của bạn từ đó với một chút công việc. Đây sẽ là cách linh hoạt nhất để đi.

ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();

5
Cảm ơn vì mẹo này! Tôi đã thêm những thứ này và nó hoạt động như một bùa mê: var imageExtensions = string.Join(";", ImageCodecInfo.GetImageDecoders().Select(ici => ici.FilenameExtension)); dialog.Filter = string.Format("Images|{0}|All Files|*.*", imageExtensions);
atlantis

ugh ... không chắc chắn cách thực hiện các khối mã nhiều dòng trong một nhận xét: |
atlantis

1
Không phải tác giả gốc :)
atlantis

9

Chỉ cần một sự cần thiết cho việc sử dụng chuỗi.Join và 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

Đối với những người không muốn nhớ cú pháp mọi lúc ở đây là cách đóng gói đơn giản:

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

Sử dụng:

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

Để khớp với danh sách các loại tệp khác nhau, bạn có thể sử dụng bộ lọc như thế này:

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

1

Điều này là cực kỳ, nhưng tôi đã xây dựng một bộ lọc điều khiển cơ sở dữ liệu động bằng cách sử dụng bảng cơ sở dữ liệu 2 cột có tên FILE_TYPES, với tên trường EXTENSION và DOCTYPE:

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

Rõ ràng tôi có nhiều loại và phần mở rộng khác nhau, nhưng tôi đơn giản hóa nó cho ví dụ này. Đây là chức năng của tôi:

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

Nên mang lại một bộ lọc trông như thế này:

nhập mô tả hình ảnh ở đây


Downvoter, quan tâm để giải thích? Bạn có một ý tưởng tốt hơn? Của tôi hoạt động, như tôi đã chứng minh thông qua một đồ họa.
vapcguy

2
Filter="Document files (*.doc,*.docx,*.pdf)|*.doc;*.docx,*.pdf|Image files (*.bmp,*.jpg)|*.bmp;*.jpg";và điều này sẽ mang lại một bộ lọc trông giống như hình ảnh cuối cùng trong câu trả lời ở trên.
mjb

@mjb Nếu bạn nhìn vào câu trả lời của tôi, bạn sẽ thấy tôi đã có nó trong phần bình luận ở đầu mã. Nếu nó không hoạt động, tôi sẽ không có đồ họa để chứng minh rằng nó làm được. Như tôi đã giải thích, mã lấy các giá trị từ bảng cơ sở dữ liệu và ghép chúng lại. Bạn chỉ cần đặt Doctype ("Tài liệu", "Hình ảnh", v.v.) và Phần mở rộng dưới dạng 2 cột trên một bảng có tên "FILE_TYPES". Giả sử bạn có một hàm được gọi DataLayer.Get_DataTable()sẽ nhận các lệnh SQL tôi có trong mã này và gửi lại cho bạn một DataTable, nó sẽ làm mọi thứ cho bạn. Như tôi đã nói, vâng, là cực đoan, nhưng nó hoạt động.
vapcguy

Đúng. nhưng em ... chỉ có 10% bài viết của bạn là câu trả lời trực tiếp cho câu hỏi. 90% khác là thông tin bổ sung không cần thiết để giải quyết câu hỏi. Câu hỏi không yêu cầu thông tin về việc lấy dữ liệu từ cơ sở dữ liệu và không hỏi về nối ... và bla ... bla ... bla .... một số lệnh SQL nữa? ... Bảng dữ liệu? Tại sao bạn không bao gồm kéo dữ liệu từ Dịch vụ web ... và trình diễn phân tích chuỗi JSON .. hoặc chuyển đổi dữ liệu XML để lấy Loại tệp? và cũng từ NoQuery? và gọi Javascript từ mặt trước đến mặt sau cho Loại tệp? .... không ... đó là ngoài chủ đề.
mjb

@mjb Điểm đã thực hiện, nhưng đó cũng là để chứng minh sức mạnh của foreachvòng lặp đó ở giữa. Bạn có thể có TẤN các loại tài liệu khác nhau và các tiện ích mở rộng trong đó. Điều này phục vụ như một cách để tổ chức chúng, sau đó áp dụng mã để có được chúng. Đối với tôi, nó tốt hơn là chỉ giả sử chỉ có 3 cái và đưa ra chuỗi nối. Dạy một người đàn ông câu cá ....
vapcguy
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.