【问题标题】:Setting the filter to an OpenFileDialog to allow the typical image formats?将过滤器设置为 OpenFileDialog 以允许典型的图像格式?
【发布时间】:2011-01-05 08:35:53
【问题描述】:

我有这个代码,我怎样才能让它接受所有典型的图像格式? 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,但其他类型呢?

【问题讨论】:

    标签: c# winforms openfiledialog


    【解决方案1】:

    来自the docs,您需要的过滤器语法如下:

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

    即用分号分隔多个扩展名 - 因此,Image Files|*.jpg;*.jpeg;*.png;...

    【讨论】:

      【解决方案2】:

      这是 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 添加支持的图像类型。谢谢
      • 我非常喜欢这个,我已经把它变成了世界上最恶心的单线! 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,我有时会想你
      • 不使用Substring(x)获取codecName如下:string codecName = string.Format("{0} files", c.FormatDescription);
      【解决方案3】:

      完整的 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  
          }
      } 
      

      【讨论】:

        【解决方案4】:

        要过滤图像文件,请使用此代码示例。

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

        【讨论】:

          【解决方案5】:

          我最喜欢 Tom Faust 的回答。这是他的解决方案的 C# 版本,但稍微简化了一点。

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

          【讨论】:

            【解决方案6】:

            对于图像,您可以从 GDI (System.Drawing) 获取可用的编解码器,并通过一些工作来构建您的列表。这将是最灵活的方式。

            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
            

            【讨论】:

            • 感谢您的提示!我添加了这些,它就像一个魅力:var imageExtensions = string.Join(";", ImageCodecInfo.GetImageDecoders().Select(ici =&gt; ici.FilenameExtension));dialog.Filter = string.Format("Images|{0}|All Files|*.*", imageExtensions);
            • 呃...不确定如何在评论中执行多行代码块:|
            • 不是原作者:)
            【解决方案7】:

            只是一个关于使用 string.Join 和 LINQ 的 necrocomment。

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

            【讨论】:

              【解决方案8】:

              对于那些不想每次都记住语法的人来说,这里是一个简单的封装:

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

              【讨论】:

                【解决方案9】:

                为了匹配一个不同类别的文件列表,你可以像这样使用过滤器:

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

                【讨论】:

                  【解决方案10】:

                  这很极端,但我使用名为 FILE_TYPES 的 2 列数据库表构建了一个动态的、数据库驱动的过滤器,字段名称为 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];
                              ...
                  

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

                  【讨论】:

                  • 投反对票,想解释一下吗?你有更好的主意吗?我的作品,正如我通过图形展示的那样。
                  • Filter="Document files (*.doc,*.docx,*.pdf)|*.doc;*.docx,*.pdf|Image files (*.bmp,*.jpg)|*.bmp;*.jpg"; 这应该会产生一个看起来像上面答案中的最后一张图片的过滤器。
                  • @mjb 如果您查看我的答案,您会发现我已经在代码顶部的注释中找到了答案。如果它不起作用,我就没有图形来证明它起作用了。正如我所解释的,代码从数据库表中获取值并将它们连接起来。您只需将 Doctype(“Documents”、“Images”等)和 Extension 作为 2 列放在名为“FILE_TYPES”的表上。假设您有一个名为DataLayer.Get_DataTable() 的函数,它将接受我在此代码中的 SQL 命令并将数据表发回给您,它会为您做所有事情。正如我所说,是的,这是极端的,但它确实有效。
                  • 是的。但是他们……你的帖子中只有 10% 是对这个问题的直接回答。其他 90% 是解决问题所不需要的额外信息。该问题不要求有关从数据库获取数据的信息,也没有询问连接...和bla...bla...bla....还有一些SQL命令? ...数据表?为什么不包括从 Web 服务中提取数据……并演示 JSON 字符串解析……或 XML 数据转换以获取文件类型?还有来自 NoSQL?以及从前端到后端的文件类型的 Javascript 调用?....不...这超出了主题。
                  • @mjb 点了,但这也是为了展示中间那个foreach 循环的力量。您可能有大量不同的文档类型,以及其中的扩展。这是一种组织它们的方式,然后应用代码来获取它们。对我来说,这比假设每个只有 3 个并给出连接字符串要好。教人钓鱼....
                  【解决方案11】:

                  使用此方法返回从ImageCodecInfo 构建的过滤器兼容字符串,支持当前系统理解的图像格式。

                          /// <summary>
                          /// Get the Filter string for all supported image types.
                          /// To be used in the FileDialog class Filter Property.
                          /// </summary>
                          /// <returns></returns>
                          public static string GetImageFilter()
                          {
                              string imageExtensions = string.Empty;
                              string separator = "";
                              ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
                              Dictionary<string, string> imageFilters = new Dictionary<string, string>();
                              foreach (ImageCodecInfo codec in codecs)
                              {
                                  imageExtensions = $"{imageExtensions}{separator}{codec.FilenameExtension.ToLower()}";
                                  separator = ";";
                                  imageFilters.Add($"{codec.FormatDescription} files ({codec.FilenameExtension.ToLower()})", codec.FilenameExtension.ToLower());
                              }
                              string result = string.Empty;
                              separator = "";
                              foreach (KeyValuePair<string, string> filter in imageFilters)
                              {
                                  result += $"{separator}{filter.Key}|{filter.Value}";
                                  separator = "|";
                              }
                              if (!string.IsNullOrEmpty(imageExtensions))
                              {
                                  result += $"{separator}Image files|{imageExtensions}";
                              }
                              return result;
                          }
                  

                  结果如图:

                  【讨论】:

                    【解决方案12】:

                    您必须包含所有图像类型扩展名并允许所有文件作为选项。

                    所有文件|.|所有图片|.jpg;.jpeg;.png;.gif;.tif; .bmp|JPEG 图片|.jpg|PNG 图片|.png";

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2020-02-11
                      • 1970-01-01
                      • 1970-01-01
                      • 2012-03-15
                      • 2011-04-26
                      相关资源
                      最近更新 更多