2011-04-20 15 views
6

Estoy usando WPF OpenFileDialog y SaveFileDialog en mi .NET 4 aplicación WPF. Uso la propiedad Filter para permitir al usuario establecer diferentes filtros de archivos. En .NET 4, esto usa los diálogos de archivos nativos introducidos con Windows Vista (si es posible).Ocultar extensiones en Vista/Windows 7 WPF FileDialog.Filter

Sin embargo, estos cuadros de diálogo muestran las extensiones que componen los filtros de archivos. Como algunos de estos usan bastante extensiones, esto es bastante feo.

Por ejemplo, tengo un filtro Image files|*.bmp;*.dib;*.jpg;*.jpeg;*.jpe;*.jfif;*.gif;*.tif;*.tiff;*.png;*.ico|All files|*.*, que se muestra como Image files (*.bmp;*.dib;*.jpg;*.jpeg;*.jpe;*.jfif;*.gif;*.tif;*.tiff;*.png;*.ico) en el cuadro de diálogo. Todo en el paréntesis se agrega automáticamente, es decir, de acuerdo con la cadena de filtro, debe mostrar Image files. Pero en algún lugar se agrega lo que está entre paréntesis. Traté de ver el código con Reflector para ver si se hace en algún lugar, pero me rindí rápidamente ya que es bastante intrincado.

Iniciando Paint, por ejemplo, puedo ver que es posible utilizar estos diálogos de archivos sin las cosas entre paréntesis, es decir, muestra Image files.

¿Alguien conoce una solución para esta "característica"?

+1

nunca he visto el comportamiento, donde los elementos filtrantes se añaden automáticamente. ¿Cuál es el espacio de nombre completo de OpenFileDialog que está utilizando? –

+0

lol acaba de probar esto en VS 2010 en Windows 7 y ahora obtengo el mismo ... –

+0

Estoy usando el Microsoft.Win32.OpenFileFilter. No hay elementos de filtro agregados automáticamente. Más bien, las cosas en el paréntesis se agregan automáticamente. –

Respuesta

5

Estás en el camino correcto. Hay efectivamente 2 formas de mostrar un cuadro de diálogo de archivo abierto. El método más nuevo usa IFileOpenDialog (que se extiende IFileDialog). Con este método, las descripciones del filtro y las especificaciones del archivo se definen utilizando la estructura COMDLG_FILTERSPEC. Esto mantiene a los separados en sus propios campos, que es más naturaleza.

Si desea eliminar las especificaciones del archivo del cuadro combinado con este método, deberá agregar su propio control personalizado o manipular el control del cuadro combinado en el cuadro de diálogo. Sin embargo, esto sería complicado, pero debería ser factible.

El método de la vieja escuela usa GetOpenFileName y la estructura OPENFILENAME. El truco con este, es que puede mostrar un diálogo con el aspecto anterior o el nuevo. La apariencia está determinada por la configuración en la estructura OPENFILENAME, como se describe en here.

El problema con el WinForms OpenFileDialog es que o bien usan IFileOpenDialog cuando dicen que AutoUpgradeEnabled es verdadero, y GetOpenFileName con el aspecto anterior cuando AutoUpgradeEnabled es falso.

La versión WPF no le permite elegir, pero sigue usando la misma lógica que WinForms, pero lo hace automáticamente según sea necesario. Esto es cierto para WPF en .NET 4, en versiones anteriores simplemente usaría GetOpenFileName con el aspecto antiguo.

Es muy probable que Paint use GetOpenFileName con la nueva apariencia. Aquí es un ejemplo de C#:

private delegate IntPtr WndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); 

private const int OFN_ALLOWMULTISELECT = 0x00000200; 
private const int OFN_CREATEPROMPT = 0x00002000; 
private const int OFN_DONTADDTORECENT = 0x02000000; 
private const int OFN_ENABLEHOOK = 0x00000020; 
private const int OFN_ENABLEINCLUDENOTIFY = 0x00400000; 
private const int OFN_ENABLESIZING = 0x00800000; 
private const int OFN_ENABLETEMPLATE = 0x00000040; 
private const int OFN_ENABLETEMPLATEHANDLE = 0x00000080; 
private const int OFN_EXPLORER = 0x00080000; 
private const int OFN_EXTENSIONDIFFERENT = 0x00000400; 
private const int OFN_FILEMUSTEXIST = 0x00001000; 
private const int OFN_FORCESHOWHIDDEN = 0x10000000; 
private const int OFN_HIDEREADONLY = 0x00000004; 
private const int OFN_LONGNAMES = 0x00200000; 
private const int OFN_NOCHANGEDIR = 0x00000008; 
private const int OFN_NODEREFERENCELINKS = 0x00100000; 
private const int OFN_NOLONGNAMES = 0x00040000; 
private const int OFN_NONETWORKBUTTON = 0x00020000; 
private const int OFN_NOREADONLYRETURN = 0x00008000; 
private const int OFN_NOTESTFILECREATE = 0x00010000; 
private const int OFN_NOVALIDATE = 0x00000100; 
private const int OFN_OVERWRITEPROMPT = 0x00000002; 
private const int OFN_PATHMUSTEXIST = 0x00000800; 
private const int OFN_READONLY = 0x00000001; 
private const int OFN_SHAREAWARE = 0x00004000; 
private const int OFN_SHOWHELP = 0x00000010; 

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 
public class OPENFILENAME_I { 
    public int lStructSize; 
    public IntPtr hwndOwner; 
    public IntPtr hInstance; 
    public string lpstrFilter; 
    public IntPtr lpstrCustomFilter; 
    public int nMaxCustFilter; 
    public int nFilterIndex; 
    public IntPtr lpstrFile; 
    public int nMaxFile = 260; 
    public IntPtr lpstrFileTitle; 
    public int nMaxFileTitle = 260; 
    public string lpstrInitialDir; 
    public string lpstrTitle; 
    public int Flags; 
    public short nFileOffset; 
    public short nFileExtension; 
    public string lpstrDefExt; 
    public IntPtr lCustData; 
    public WndProc lpfnHook; 
    public string lpTemplateName; 
    public IntPtr pvReserved; 
    public int dwReserved; 
    public int FlagsEx; 
} 

[DllImport("comdlg32.dll", CharSet = CharSet.Unicode, SetLastError = true)] 
private static extern bool GetOpenFileName([In, Out] OPENFILENAME_I ofn); 

private void ShowOpenFileDialog() { 
    OPENFILENAME_I ofn = new OPENFILENAME_I(); 
    ofn.lStructSize = Marshal.SizeOf(typeof(OPENFILENAME_I)); 
    ofn.lpstrFilter = "Text Files (*.txt)\0*.txt\0All Files\0*.*\0\0"; 
    ofn.nFilterIndex = 0; 
    //ofn.Flags = OFN_EXPLORER | OFN_ENABLEHOOK | OFN_ENABLESIZING | OFN_NODEREFERENCELINKS | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; 
    ofn.Flags = OFN_ENABLESIZING | OFN_NODEREFERENCELINKS | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; 
    GetOpenFileName(ofn); 
} 

Usted puede tratar de añadir los OFN_EXPLORER/OFN_ENABLEHOOK o banderas y de nuevo, y se volverá a la vieja mirada.Pero tal como está, el código anterior mostrará un cuadro de diálogo de archivo abierto en el que All Files no muestra su especificación de archivo.

+0

Muchas gracias. Supongo que me saltearé esto, ya que resultará en mucho trabajo para una mejora menor que la mayoría de los usuarios no notarán ... –

1

Después de un montón de pruebas, obtuve el siguiente resultado: El FileDialog en WPF llama al método nativo IFileDialog::SetFileTypes con las cadenas como se define en el filtro. Dependiendo de la opción de Windows para ocultar la extensión en tipos de archivos conocidos (en la configuración de la carpeta del Explorador de Windows), las extensiones se agregan automáticamente o no.

Ahora, la única pregunta que queda es cómo Paint no puede mostrar las extensiones de "Archivos de imagen" en su cuadro de diálogo de archivo abierto.

Cuestiones relacionadas