将过滤器设置为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,但是其他类型是什么?

Answers:


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

我最喜欢汤姆·浮士德的答案。这是他的解决方案的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)2014年

嗯...不确定在注释中如何执行多行代码块:|
亚特兰蒂斯2014年

1
不是原始作者:)
亚特兰蒂斯

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

这是极端的情况,但是我使用名为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];
            ...

应该产生一个看起来像这样的过滤器:

在此处输入图片说明


唐纳德,关心解释吗?你有更好的主意吗?我通过图形演示了我的作品。
vapcguy

2
Filter="Document files (*.doc,*.docx,*.pdf)|*.doc;*.docx,*.pdf|Image files (*.bmp,*.jpg)|*.bmp;*.jpg";这将产生一个看起来像上面答案中最后一张图片的过滤器。
mjb

@mjb如果您查看我的答案,您会发现我已经在代码顶部的注释中找到了它。如果它不起作用,我将没有图形来证明它确实可行。正如我所解释的,代码从数据库表中获取值并将它们连接起来。您只需将Doctype(“文档”,“图像”等)和扩展名放在名为“ FILE_TYPES”的表上的2列中。假设您有一个名为的函数DataLayer.Get_DataTable(),它将使用我在此代码中拥有的SQL命令并将您发送回DataTable,它将为您完成所有工作。正如我说的,是的,这是极端的,但确实有效。
vapcguy

是。但是em ...您的帖子中只有10%是该问题的直接答案。其他90%是不需要解决该问题的额外信息。该问题不要求提供有关从数据库获取数据的信息,也没有询问有关连接的信息……等等……等等……还有更多的SQL命令吗?...数据表?您为什么还不包括从Web服务中提取数据...,并演示JSON字符串解析..或XML数据转换以获取文件类型?还有NoSQL吗?以及从前端到后端为文件类型调用Javascript?
mjb

@mjb指出了这一点,但这也是为了演示该foreach循环在中间的作用。您可能拥有不同文档类型的TONS,以及其中的扩展名。这是一种组织它们,然后应用代码来获取它们的方法。对我来说,这比仅假设每个对象只有3个并给出串联字符串要好。教人以鱼... ...
vapcguy
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.