diff --git a/src/System.Windows.Forms.Design/src/PublicAPI.Unshipped.txt b/src/System.Windows.Forms.Design/src/PublicAPI.Unshipped.txt
index e69de29bb2d..d5929c4099f 100644
--- a/src/System.Windows.Forms.Design/src/PublicAPI.Unshipped.txt
+++ b/src/System.Windows.Forms.Design/src/PublicAPI.Unshipped.txt
@@ -0,0 +1 @@
+virtual System.Windows.Forms.Design.FolderNameEditor.InitializeDialog(System.Windows.Forms.FolderBrowserDialog! folderBrowserDialog) -> void
diff --git a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/FolderNameEditor.cs b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/FolderNameEditor.cs
index 49c1d937950..aff82a81648 100644
--- a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/FolderNameEditor.cs
+++ b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/FolderNameEditor.cs
@@ -12,19 +12,19 @@ namespace System.Windows.Forms.Design;
[CLSCompliant(false)]
public partial class FolderNameEditor : UITypeEditor
{
- private FolderBrowser? _folderBrowser;
-
public override object? EditValue(ITypeDescriptorContext? context, IServiceProvider provider, object? value)
{
- if (_folderBrowser is null)
- {
- _folderBrowser = new FolderBrowser();
- InitializeDialog(_folderBrowser);
- }
+ // The dialog is created locally and disposed at the end of the call so its
+ // native resources (Component/CommonDialog state) are released, and no stale
+ // configuration leaks between successive invocations of EditValue.
+ using FolderBrowserDialog folderBrowserDialog = new();
+ InitializeDialog(folderBrowserDialog);
- if (_folderBrowser.ShowDialog() == DialogResult.OK)
+ folderBrowserDialog.SelectedPath = value as string ?? string.Empty;
+
+ if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
{
- return _folderBrowser.DirectoryPath;
+ return folderBrowserDialog.SelectedPath;
}
return value;
@@ -37,7 +37,17 @@ public partial class FolderNameEditor : UITypeEditor
/// Initializes the folder browser dialog when it is created. This gives you an opportunity
/// to configure the dialog as you please. The default implementation provides a generic folder browser.
///
+ [Obsolete]
+ [EditorBrowsable(EditorBrowsableState.Never)]
protected virtual void InitializeDialog(FolderBrowser folderBrowser)
{
}
+
+ ///
+ /// Initializes the folder browser dialog when it is created. This gives you an opportunity
+ /// to configure the dialog as you please. The default implementation provides a generic folder browser.
+ ///
+ protected virtual void InitializeDialog(FolderBrowserDialog folderBrowserDialog)
+ {
+ }
}
diff --git a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/InitialDirectoryEditor.cs b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/InitialDirectoryEditor.cs
index 00ab84f5c3c..03d9e74beec 100644
--- a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/InitialDirectoryEditor.cs
+++ b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/InitialDirectoryEditor.cs
@@ -8,8 +8,8 @@ namespace System.Windows.Forms.Design;
///
internal class InitialDirectoryEditor : FolderNameEditor
{
- protected override void InitializeDialog(FolderBrowser folderBrowser)
+ protected override void InitializeDialog(FolderBrowserDialog folderBrowserDialog)
{
- folderBrowser.Description = SR.InitialDirectoryEditorLabel;
+ folderBrowserDialog.Description = SR.InitialDirectoryEditorLabel;
}
}
diff --git a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/SelectedPathEditor.cs b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/SelectedPathEditor.cs
index 037d9f44c42..350805e75e6 100644
--- a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/SelectedPathEditor.cs
+++ b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/SelectedPathEditor.cs
@@ -8,8 +8,8 @@ namespace System.Windows.Forms.Design;
///
internal class SelectedPathEditor : FolderNameEditor
{
- protected override void InitializeDialog(FolderBrowser folderBrowser)
+ protected override void InitializeDialog(FolderBrowserDialog folderBrowserDialog)
{
- folderBrowser.Description = SR.SelectedPathEditorLabel;
+ folderBrowserDialog.Description = SR.SelectedPathEditorLabel;
}
}
diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/FolderNameEditorTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/FolderNameEditorTests.cs
index cfb9ee97af3..1b7bc3c60cb 100644
--- a/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/FolderNameEditorTests.cs
+++ b/src/System.Windows.Forms.Design/tests/UnitTests/System/Windows/Forms/Design/FolderNameEditorTests.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
#nullable disable
@@ -38,71 +38,24 @@ public void FolderNameEditor_GetPaintValueSupported_Invoke_ReturnsFalse(ITypeDes
public void FolderNameEditor_InitializeDialog_Invoke_Nop()
{
SubFolderNameEditor editor = new();
- editor.InitializeDialog();
- }
-
- public class FolderBrowserTests : FolderNameEditor
- {
- [Fact]
- public void FolderBrowser_Ctor_Default()
- {
- FolderBrowser browser = new();
- Assert.Empty(browser.DirectoryPath);
- Assert.Empty(browser.Description);
- Assert.Equal(FolderBrowserStyles.RestrictToFilesystem, browser.Style);
- Assert.Equal(FolderBrowserFolder.Desktop, browser.StartLocation);
- }
-
- [Theory]
- [NormalizedStringData]
- public void FolderBrowser_Description_Set_GetReturnsExpected(string value, string expected)
- {
- FolderBrowser browser = new()
- {
- Description = value
- };
- Assert.Equal(expected, browser.Description);
-
- // Set same.
- browser.Description = value;
- Assert.Equal(expected, browser.Description);
- }
-
- [Theory]
- [EnumData]
- [InvalidEnumData]
- protected void FolderBrowser_StartLocation_Set_GetReturnsExpected(FolderBrowserFolder value)
- {
- FolderBrowser browser = new()
- {
- StartLocation = value
- };
- Assert.Equal(value, browser.StartLocation);
+ using FolderBrowserDialog dialog = new();
- // Set same.
- browser.StartLocation = value;
- Assert.Equal(value, browser.StartLocation);
- }
+ // The base implementation is intentionally a no-op; invoking it should not
+ // throw and should leave the dialog's defaults untouched.
+ string originalSelectedPath = dialog.SelectedPath;
+ string originalDescription = dialog.Description;
+ Environment.SpecialFolder originalRootFolder = dialog.RootFolder;
- [Theory]
- [EnumData]
- [InvalidEnumData]
- protected void FolderBrowser_Style_Set_GetReturnsExpected(FolderBrowserStyles value)
- {
- FolderBrowser browser = new()
- {
- Style = value
- };
- Assert.Equal(value, browser.Style);
+ editor.InitializeDialog(dialog);
- // Set same.
- browser.Style = value;
- Assert.Equal(value, browser.Style);
- }
+ Assert.Equal(originalSelectedPath, dialog.SelectedPath);
+ Assert.Equal(originalDescription, dialog.Description);
+ Assert.Equal(originalRootFolder, dialog.RootFolder);
}
private class SubFolderNameEditor : FolderNameEditor
{
- public void InitializeDialog() => base.InitializeDialog(null);
+ public new void InitializeDialog(FolderBrowserDialog folderBrowserDialog) =>
+ base.InitializeDialog(folderBrowserDialog);
}
}
diff --git a/src/test/integration/UIIntegrationTests/FolderNameEditorTests.cs b/src/test/integration/UIIntegrationTests/FolderNameEditorTests.cs
index d39106f790f..4c2cf105256 100644
--- a/src/test/integration/UIIntegrationTests/FolderNameEditorTests.cs
+++ b/src/test/integration/UIIntegrationTests/FolderNameEditorTests.cs
@@ -30,21 +30,21 @@ public void FolderNameEditor_EditValue_ReturnsExpected()
private class TestFolderNameEditor : FolderNameEditor
{
- private FolderBrowser? _folderBrowser;
+ private FolderBrowserDialog? _folderBrowserDialog;
public override object? EditValue(ITypeDescriptorContext? context, IServiceProvider provider, object? value)
{
using DialogHostForm dialogOwnerForm = new();
- if (_folderBrowser is null)
+ if (_folderBrowserDialog is null)
{
- _folderBrowser = new FolderBrowser();
- InitializeDialog(_folderBrowser);
+ _folderBrowserDialog = new FolderBrowserDialog();
+ InitializeDialog(_folderBrowserDialog);
}
- if (_folderBrowser.ShowDialog(dialogOwnerForm) == DialogResult.OK)
+ if (_folderBrowserDialog.ShowDialog(dialogOwnerForm) == DialogResult.OK)
{
- return _folderBrowser.DirectoryPath;
+ return _folderBrowserDialog.SelectedPath = value as string ?? string.Empty;
}
return value;