{"record":{"id":"3358949744b4d622","repo":"MahApps/MahApps.Metro","slug":"the-provided-dialog-is-already-visible-in-the-spec","errorCode":null,"errorMessage":"The provided dialog is already visible in the specified window.","messagePattern":"The provided dialog is already visible in the specified window\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/MahApps.Metro/Controls/Dialogs/DialogManager.cs","lineNumber":301,"sourceCode":"        /// <returns>A task representing the operation.</returns>\n        /// <exception cref=\"InvalidOperationException\">The <paramref name=\"dialog\"/> is already visible in the window.</exception>\n        public static async Task ShowMetroDialogAsync(this MetroWindow window, BaseMetroDialog dialog, MetroDialogSettings? settings = null)\n        {\n            window.Dispatcher.VerifyAccess();\n\n            if (window.metroActiveDialogContainer is null)\n            {\n                throw new InvalidOperationException(\"Active dialog container could not be found.\");\n            }\n\n            if (window.metroInactiveDialogContainer is null)\n            {\n                throw new InvalidOperationException(\"Inactive dialog container could not be found.\");\n            }\n\n            if (window.metroActiveDialogContainer.Children.Contains(dialog) || window.metroInactiveDialogContainer.Children.Contains(dialog))\n            {\n                throw new InvalidOperationException(\"The provided dialog is already visible in the specified window.\");\n            }\n\n            settings ??= dialog.DialogSettings;\n\n            await HandleOverlayOnShowAsync(settings, window);\n\n            SetDialogFontSizes(settings, dialog);\n\n            dialog.SizeChangedHandler = SetupAndAddDialog(window, dialog);\n\n            await dialog.WaitForLoadAsync();\n\n            DialogOpened?.Invoke(window, new DialogStateChangedEventArgs(dialog));\n        }\n\n        /// <summary>\n        /// Adds a Metro Dialog instance of the given type to the specified window and makes it visible asynchronously.\n        /// If you want to wait until the user has closed the dialog, use <see cref=\"BaseMetroDialog.WaitUntilUnloadedAsync\"/>","sourceCodeStart":283,"sourceCodeEnd":319,"githubUrl":"https://github.com/MahApps/MahApps.Metro/blob/72099e310bac2d12ac98fd7560b69679252519f5/src/MahApps.Metro/Controls/Dialogs/DialogManager.cs#L283-L319","documentation":"Thrown by ShowMetroDialogAsync when the dialog instance is already present in either the window's active or inactive dialog container. MahApps.Metro enforces one logical instance per window to prevent double-overlay and duplicate focus capture. The guard runs before overlay/font setup so a re-show would corrupt the dialog z-order stack.","triggerScenarios":"Calling window.ShowMetroDialogAsync(sameDialogInstance) twice without an intervening HideMetroDialogAsync; re-showing a dialog from a click handler that already fired; awaiting ShowMetroDialogAsync then calling it again on the same reference in a continuation.","commonSituations":"A 'Show Settings' button whose handler isn't debounced and fires twice on rapid double-click; reusing a cached BaseMetroDialog field across open/close cycles; calling ShowMetroDialogAsync from both a command and a window event with overlapping async execution.","solutions":["Track dialog lifetime: set a field to the dialog after showing and null it after HideMetroDialogAsync completes, and guard the show call on that field being null.","Debounce/guard the entry point (e.g. disable the invoking button or a CanExecute check) while a dialog is already open.","Create a fresh dialog instance per show instead of reusing the same BaseMetroDialog object.","Before re-showing, check window metroActiveDialogContainer/metroInactiveDialogContainer Children.Contains — though these are internal, prefer the lifecycle guard."],"exampleFix":"// before\nprivate SettingsDialog? _settings;\nprivate async void OnSettingsClick(object s, RoutedEventArgs e)\n{\n    await this.ShowMetroDialogAsync(_settings ??= new SettingsDialog(this));\n}\n\n// after\nprivate SettingsDialog? _settings;\nprivate async void OnSettingsClick(object s, RoutedEventArgs e)\n{\n    if (_settings is not null) return;\n    _settings = new SettingsDialog(this);\n    try { await this.ShowMetroDialogAsync(_settings); }\n    finally { await this.HideMetroDialogAsync(_settings); _settings = null; }\n}","handlingStrategy":"validation","validationCode":"// Guard against re-showing a dialog already managed by the window.\n// metroActiveDialogContainer / metroInactiveDialogContainer are internal,\n// so track shown state yourself before calling ShowMetroDialogAsync.\nprivate BaseMetroDialog? _openDialog;\n\nasync Task ShowOnceAsync(MetroWindow window, BaseMetroDialog dialog)\n{\n    if (_openDialog is not null) return;          // already showing something\n    _openDialog = dialog;\n    try { await window.ShowMetroDialogAsync(dialog); }\n    catch { _openDialog = null; throw; }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep a single field that holds the currently-open dialog and null it only after HideMetroDialogAsync completes.","Disable the invoking button or use ICommand.CanExecute while a dialog is open.","Never reuse one BaseMetroDialog instance across multiple concurrent show operations."],"tags":["wpf","dialogs","mahapps","state-management","duplicate"],"backgroundTag":null,"analyzedSha":"72099e310bac2d12ac98fd7560b69679252519f5","analyzedAt":"2026-08-13T20:19:34.419Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}