2010-01-15 8 views
171

Ho questo codice, come posso consentirgli di accettare tutti i formati di immagine tipici? PNG, JPEG, JPG, GIF?Impostazione del filtro su OpenFileDialog per consentire i tipici formati di immagine?

Ecco quello che ho finora:

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

Si noti che il filtro è impostato su file .txt. I potrebbe passare a PNG, ma che dire degli altri tipi?

risposta

211

Da the docs, la sintassi del filtro che è necessario è il seguente:

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

cioè separare i più estensioni con un punto e virgola - quindi, Image Files|*.jpg;*.jpeg;*.png;....

+0

Diritto al punto. – mjb

9

Per le immagini, è possibile ottenere i codec disponibili da GDI (System.Drawing) e creare il proprio elenco con un po 'di lavoro. Questo sarebbe il modo più flessibile per andare.

ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders(); 
+3

Grazie per questo suggerimento! Ho aggiunto questi e ha funzionato come un fascino: 'var imageExtensions = string.Join ("; ", ImageCodecInfo.GetImageDecoders(). Seleziona (ici => ici.FilenameExtension));' 'dialog.Filter = stringa .Formato ("Immagini | {0} | Tutti i file | *. *", ImageExtensions); ' – atlantis

+0

ugh ... non sono sicuro di come fare blocchi di codice su più righe in un commento: | – atlantis

+0

@atlantis Probabilmente meglio modificare il post stesso con il codice ... – vapcguy

53

Ecco un esempio di suggestione ImageCodecInfo (in VB):

 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", "*.*") 

e sembra che questo:

enter image description here

+1

Imports System.Drawing.Imaging ;-) – FastAl

37

soluzione completa in C# è qui:

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 
    } 
} 
128

seguire questo modello se la navigazione per i file di immagine:

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

Probabilmente vuoi liberarti degli spazi prima e dopo il carattere pipe e tra il punto e virgola e l'asterisco nella parte del filtro. Ma buono, altrimenti. – vapcguy

15

per filtrare i file immagini, utilizzare questo esempio di codice.

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

Solo un necrocomment per l'utilizzo di string.Join e 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())); 
2

Per coloro che non vogliono ricordare la sintassi di ogni ecco un semplice incapsulamento:

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

Usage:

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

mi piace la risposta di Tom Faust il migliore. Ecco una versione C# della sua soluzione, ma semplificando un po 'le cose.

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

Questo è estremo, ma ho costruito un filtro dinamico, basato su database utilizzando una tabella di database 2 colonna denominata FILE_TYPES, con i nomi dei campi di estensione e DOCTYPE:

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

Ovviamente ho avuto molti tipi diversi ed estensioni, ma lo sto semplificando per questo esempio.Qui è la mia funzione:

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

dovrebbe produrre un filtro che assomiglia a questo:

enter image description here

+0

Downvoter, cura di spiegare? Hai un'idea migliore? Il mio funziona, come ho dimostrato attraverso un grafico. – vapcguy

+2

'Filter =" File documento (* .doc, *. Docx, *. Pdf) | * .doc; *. Docx, *. Pdf | File immagine (* .bmp, *. Jpg) | * .bmp; * .jpg ";' e questo dovrebbe produrre un filtro che assomiglia all'ultima immagine nella risposta sopra. – mjb

+0

@mjb Se hai guardato la mia risposta, vedresti che l'avevo già nel commento nella parte superiore del codice. Se non funzionasse, non avrei la grafica per dimostrare che lo fa. Come ho spiegato, il codice prende i valori da una tabella di database e li concatena. Dovresti semplicemente inserire il Doctype ("Documenti", "Immagini", ecc.) E l'Estensione come 2 colonne su una tabella chiamata "FILE_TYPES". Supponendo che tu avessi una funzione chiamata 'DataLayer.Get_DataTable()' che prenderebbe i comandi SQL che ho in questo codice e ti rimanderebbe un DataTable, farebbe tutto per te. Come ho detto, sì, era estremo, ma funziona. – vapcguy

1

Al fine di corrispondere a un elenco di categorie diverse di file, è possibile utilizzare il filtro in questo modo:

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