none
InitialDirectory-Eigenschaft bei OpenFileDialog funktioniert nicht nach Öffnen eines anderen Verzeichnisses RRS feed

  • Frage

  • Ich arbeite an einer WPF-Anwendung, in der ich an zwei verschiedenen Stellen Dateien öffne.

    Im ersten Fall handelt es sich um XML- und im anderen um Bild-Dateien.

    Die Verzeichnispfade habe ich in der app.config abgelegt und verwende diese beim Setzen der InitialDirectory-Eigenschaft des OpenFileDialog.

    Zuerst öffne ich in WPF-Window-A eine XML-Datei, wobei das Initialverzeichnis korrekt eingestellt ist - so weit, so gut.

    Dann möchte ich in WPF-Window-B eine Bild-Datei öffnen, aber hier hat der OpenFileDialog noch immer den alten Verzeichnispfad.

    Wenn ich diesen nun umstelle und wieder in WPF-Window-A ein XML öffnen möchte, hat der OpenFileDialog noch immer den Verzeichnispfad der Bilder.

    RestoreDirectory habe ich inzwischen auch schon ohne Erfolg auf true und false umgestellt.

    Welcher Fehler ist mir unterlaufen?

    Hier der Code zum Öffnen der XML-Dateien:

            private void openXMLFile(object sender, RoutedEventArgs e)
            {
                System.Windows.Forms.OpenFileDialog fileDialog = new System.Windows.Forms.OpenFileDialog();
                fileDialog.InitialDirectory = System.Configuration.ConfigurationManager.AppSettings["SerializedXmlFolderPath"].ToString();
                fileDialog.Filter = "xml files (*.xml)|*.xml";
                fileDialog.FilterIndex = 1;
                fileDialog.RestoreDirectory = false;
    
                if (fileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
                    string fileNameWithType = fileDialog.SafeFileName.Trim();
                    if (fileNameWithType == null || fileNameWithType.Length < 5 || !fileNameWithType.EndsWith(".xml")) {
                        MessageBox.Show("This is not a file name, that can be used!");
                        return;
                    }
                    formularsCommonName = fileNameWithType.Substring(0, fileNameWithType.Length - 4);
                    directory = Path.GetDirectoryName(fileDialog.FileName) + Path.DirectorySeparatorChar;
                    string fileName = directory + formularsCommonName + ".xml";
                    loadXMLFile(fileName);
                    formularCounter = 0;
                }
                fileDialog.Dispose();
            }
    

    Und der Code zum Laden der Bilder:

            private void btn_searchImageFile_Click(object sender, RoutedEventArgs e)
            {
                System.Windows.Forms.OpenFileDialog fileDialog = new System.Windows.Forms.OpenFileDialog();
                fileDialog.InitialDirectory = System.Configuration.ConfigurationManager.AppSettings["ImageFolderPath"].ToString();
                fileDialog.Filter = "Image files (*.bmp, *.jpg, *.png)|*.bmp;*.jpg;*.png";
                fileDialog.FilterIndex = 1;
                fileDialog.RestoreDirectory = false;
    
                if (fileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    string imageFilePath = fileDialog.FileName;
                    changeTextProperties.ImageFilePath = imageFilePath;
                }
                fileDialog.Dispose();
            }
    

    Freitag, 16. September 2016 11:06

Antworten

  • Hallo Patrick,

    das kann ich nicht nachvollziehen, egal wie ich die Dateien auswähle, kommt das InitialDirectory zum Tragen.

    Die RestoreDirectory Eigenschaft ist wirkungslos, siehe OPENFILENAME und dort FN_NOCHANGEDIR, dem es entspricht. Es gab ältere Varianten, die sich anders verhielten, siehe What does the FileDialog.RestoreDirectory Property actually do?

    Im übrigen hat WPF seine eigene Variante unter Microsoft.Win32, so dass Du die Windows Forms.dll dafür nicht einbinden musst. Auch solltest Du den "Prüfcode" etwas überarbeiten - so sind Windows Dateinamen case-insensitiv[1] - und durchweg Methoden der Path Klasse verwenden. Eine Möglichkeit wäre:

                var fileDialog = new Microsoft.Win32.OpenFileDialog();
                fileDialog.InitialDirectory = Properties.Settings.Default.SerializedXmlFolderPath;
                fileDialog.Filter = "xml files (*.xml)|*.xml";
                fileDialog.FilterIndex = 1;
                // nicht aktiv, siehe OFN_NOCHANGEDIR https://msdn.microsoft.com/en-us/library/windows/desktop/ms646839(v=vs.85).aspx
                // fileDialog.RestoreDirectory = false; 
    
                if (fileDialog.ShowDialog() == true)
                {
                    // nur xml, dann passt auch der Rest
                    if (Path.GetExtension(fileDialog.SafeFileName).Equals(".xml", StringComparison.OrdinalIgnoreCase))
                    {
                        string xmlFileName = fileDialog.FileName;
                        Console.WriteLine(xmlFileName);
                    }
                    else
                    {
                        MessageBox.Show("Please choose a file with a Xml extension."); 
                    }
                }
                else
                {
                    Debug.WriteLine("OpenXmlFile_Click cancelled.");
                }

    Gruß Elmar

    [1] Best Practices for Using Strings in the .NET Framework.

    Freitag, 16. September 2016 14:55

Alle Antworten

  • Hallo Patrick,

    das kann ich nicht nachvollziehen, egal wie ich die Dateien auswähle, kommt das InitialDirectory zum Tragen.

    Die RestoreDirectory Eigenschaft ist wirkungslos, siehe OPENFILENAME und dort FN_NOCHANGEDIR, dem es entspricht. Es gab ältere Varianten, die sich anders verhielten, siehe What does the FileDialog.RestoreDirectory Property actually do?

    Im übrigen hat WPF seine eigene Variante unter Microsoft.Win32, so dass Du die Windows Forms.dll dafür nicht einbinden musst. Auch solltest Du den "Prüfcode" etwas überarbeiten - so sind Windows Dateinamen case-insensitiv[1] - und durchweg Methoden der Path Klasse verwenden. Eine Möglichkeit wäre:

                var fileDialog = new Microsoft.Win32.OpenFileDialog();
                fileDialog.InitialDirectory = Properties.Settings.Default.SerializedXmlFolderPath;
                fileDialog.Filter = "xml files (*.xml)|*.xml";
                fileDialog.FilterIndex = 1;
                // nicht aktiv, siehe OFN_NOCHANGEDIR https://msdn.microsoft.com/en-us/library/windows/desktop/ms646839(v=vs.85).aspx
                // fileDialog.RestoreDirectory = false; 
    
                if (fileDialog.ShowDialog() == true)
                {
                    // nur xml, dann passt auch der Rest
                    if (Path.GetExtension(fileDialog.SafeFileName).Equals(".xml", StringComparison.OrdinalIgnoreCase))
                    {
                        string xmlFileName = fileDialog.FileName;
                        Console.WriteLine(xmlFileName);
                    }
                    else
                    {
                        MessageBox.Show("Please choose a file with a Xml extension."); 
                    }
                }
                else
                {
                    Debug.WriteLine("OpenXmlFile_Click cancelled.");
                }

    Gruß Elmar

    [1] Best Practices for Using Strings in the .NET Framework.

    Freitag, 16. September 2016 14:55
  • Vielen Dank Elmar.

    Du hast Recht, das Problem lag nicht an dem Code für den OpenFileDialog, sondern an den Settings in der app.config.

    Hier hatte ich versehentlich die Pfade im C#-Stil hinterlegt, also mit "\\" statt "\".

    Darum waren die InitialDirectories nicht korrekt und kamen nie zur Geltung.

    In einem solchen Fall nimm Visual Studio den zuletzt eingestellten Pfad.

    Montag, 19. September 2016 06:40