Skip to content

Commit 1fb94ea

Browse files
Added DialogHost.DialogClosed event (#2767)
* Added DialogHost.DialogClosed event Works the same way as DialogClosing, except it cannot be cancelled, and it is only fired once IsOpen changes to False. * Removed possibly ambiguous ShowDialog()/Show() overloads * Fixed failing unit test nulls allowed for local test run, but fails in CI chain.
1 parent 78c4aa3 commit 1fb94ea

File tree

8 files changed

+259
-46
lines changed

8 files changed

+259
-46
lines changed

MainDemo.Wpf/Dialogs.xaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
Grid.Row="1">
6565
<materialDesign:DialogHost
6666
DialogClosing="Sample1_DialogHost_OnDialogClosing"
67+
DialogClosed="Sample1_DialogHost_OnDialogClosed"
6768
DialogTheme="Inherit">
6869
<materialDesign:DialogHost.DialogContent>
6970
<StackPanel Margin="16">
@@ -160,6 +161,7 @@
160161
<Button
161162
Command="{x:Static materialDesign:DialogHost.OpenDialogCommand}"
162163
materialDesign:DialogHost.DialogClosingAttached="Sample2_DialogHost_OnDialogClosing"
164+
materialDesign:DialogHost.DialogClosedAttached="Sample2_DialogHost_OnDialogClosed"
163165
Width="128"
164166
Content="PASS VIEW">
165167
<Button.CommandParameter>
@@ -283,6 +285,7 @@
283285
Margin="8 8 0 0">
284286
<materialDesign:DialogHost
285287
DialogClosing="Sample5_DialogHost_OnDialogClosing"
288+
DialogClosed="Sample5_DialogHost_OnDialogClosed"
286289
Style="{StaticResource MaterialDesignEmbeddedDialogHost}"
287290
DialogMargin="8">
288291
<materialDesign:DialogHost.DialogContent>

MainDemo.Wpf/Dialogs.xaml.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,27 @@ private void Sample1_DialogHost_OnDialogClosing(object sender, DialogClosingEven
2626
FruitListBox.Items.Add(FruitTextBox.Text.Trim());
2727
}
2828

29+
private void Sample1_DialogHost_OnDialogClosed(object sender, DialogClosedEventArgs eventArgs)
30+
{
31+
Debug.WriteLine($"SAMPLE 1: Closed dialog with parameter: {eventArgs.Parameter ?? string.Empty}");
32+
33+
//you can cancel the dialog close:
34+
//eventArgs.Cancel();
35+
36+
if (!Equals(eventArgs.Parameter, true))
37+
return;
38+
39+
if (!string.IsNullOrWhiteSpace(FruitTextBox.Text))
40+
FruitListBox.Items.Add(FruitTextBox.Text.Trim());
41+
}
42+
2943
// Used for DialogHost.DialogClosingAttached
3044
private void Sample2_DialogHost_OnDialogClosing(object sender, DialogClosingEventArgs eventArgs)
3145
=> Debug.WriteLine($"SAMPLE 2: Closing dialog with parameter: {eventArgs.Parameter ?? string.Empty}");
3246

47+
private void Sample2_DialogHost_OnDialogClosed(object sender, DialogClosedEventArgs eventArgs)
48+
=> Debug.WriteLine($"SAMPLE 2: Closed dialog with parameter: {eventArgs.Parameter ?? string.Empty}");
49+
3350
private void Sample5_DialogHost_OnDialogClosing(object sender, DialogClosingEventArgs eventArgs)
3451
{
3552
Debug.WriteLine($"SAMPLE 5: Closing dialog with parameter: {eventArgs.Parameter ?? string.Empty}");
@@ -43,5 +60,16 @@ private void Sample5_DialogHost_OnDialogClosing(object sender, DialogClosingEven
4360
if (!string.IsNullOrWhiteSpace(AnimalTextBox.Text))
4461
AnimalListBox.Items.Add(AnimalTextBox.Text.Trim());
4562
}
63+
64+
private void Sample5_DialogHost_OnDialogClosed(object sender, DialogClosedEventArgs eventArgs)
65+
{
66+
Debug.WriteLine($"SAMPLE 5: Closed dialog with parameter: {eventArgs.Parameter ?? string.Empty}");
67+
68+
if (!Equals(eventArgs.Parameter, true))
69+
return;
70+
71+
if (!string.IsNullOrWhiteSpace(AnimalTextBox.Text))
72+
AnimalListBox.Items.Add(AnimalTextBox.Text.Trim());
73+
}
4674
}
4775
}

MainDemo.Wpf/Domain/DialogsViewModel.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ private async void ExecuteRunDialog(object? _)
3131
};
3232

3333
//show the dialog
34-
var result = await DialogHost.Show(view, "RootDialog", ClosingEventHandler);
34+
var result = await DialogHost.Show(view, "RootDialog", null, ClosingEventHandler, ClosedEventHandler);
3535

3636
//check the result...
3737
Debug.WriteLine("Dialog was closed, the CommandParameter used to close it was: " + (result ?? "NULL"));
@@ -40,6 +40,9 @@ private async void ExecuteRunDialog(object? _)
4040
private void ClosingEventHandler(object sender, DialogClosingEventArgs eventArgs)
4141
=> Debug.WriteLine("You can intercept the closing event, and cancel here.");
4242

43+
private void ClosedEventHandler(object sender, DialogClosedEventArgs eventArgs)
44+
=> Debug.WriteLine("You can intercept the closed event here (1).");
45+
4346
private async void ExecuteRunExtendedDialog(object? _)
4447
{
4548
//let's set up a little MVVM, cos that's what the cool kids are doing:
@@ -49,17 +52,18 @@ private async void ExecuteRunExtendedDialog(object? _)
4952
};
5053

5154
//show the dialog
52-
var result = await DialogHost.Show(view, "RootDialog", ExtendedOpenedEventHandler, ExtendedClosingEventHandler);
55+
var result = await DialogHost.Show(view, "RootDialog", ExtendedOpenedEventHandler, ExtendedClosingEventHandler, ExtendedClosedEventHandler);
5356

5457
//check the result...
5558
Debug.WriteLine("Dialog was closed, the CommandParameter used to close it was: " + (result ?? "NULL"));
5659
}
5760

58-
private void ExtendedOpenedEventHandler(object sender, DialogOpenedEventArgs eventargs)
61+
private void ExtendedOpenedEventHandler(object sender, DialogOpenedEventArgs eventArgs)
5962
=> Debug.WriteLine("You could intercept the open and affect the dialog using eventArgs.Session.");
6063

6164
private void ExtendedClosingEventHandler(object sender, DialogClosingEventArgs eventArgs)
6265
{
66+
Debug.WriteLine("You can intercept the closing event, cancel it, and do our own close after a little while.");
6367
if (eventArgs.Parameter is bool parameter &&
6468
parameter == false) return;
6569

@@ -76,6 +80,9 @@ private void ExtendedClosingEventHandler(object sender, DialogClosingEventArgs e
7680
TaskScheduler.FromCurrentSynchronizationContext());
7781
}
7882

83+
private void ExtendedClosedEventHandler(object sender, DialogClosedEventArgs eventArgs)
84+
=> Debug.WriteLine("You could intercept the closed event here (2).");
85+
7986
#endregion
8087

8188
#region SAMPLE 4

MaterialDesignThemes.Wpf.Tests/DialogHostTests.cs

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
1-
using System;
2-
using System.ComponentModel;
3-
using System.Threading.Tasks;
4-
using System.Windows;
5-
using System.Windows.Controls;
6-
using System.Windows.Input;
1+
using System.ComponentModel;
72
using Xunit;
83

94
namespace MaterialDesignThemes.Wpf.Tests
@@ -189,6 +184,34 @@ void ClosingHandler(object s, DialogClosingEventArgs e)
189184
Assert.Equal(2, closeInvokeCount);
190185
}
191186

187+
[StaFact]
188+
public async Task WhenCancellingClosingEventClosedEventHandlerIsNotInvoked()
189+
{
190+
int closingInvokeCount = 0;
191+
void ClosingHandler(object s, DialogClosingEventArgs e)
192+
{
193+
closingInvokeCount++;
194+
if (closingInvokeCount == 1)
195+
{
196+
e.Cancel();
197+
}
198+
}
199+
int closedInvokeCount = 0;
200+
void ClosedHandler(object s, DialogClosedEventArgs e)
201+
{
202+
closedInvokeCount++;
203+
}
204+
205+
var dialogTask = DialogHost.Show("Content", null, ClosingHandler, ClosedHandler);
206+
_dialogHost.CurrentSession?.Close("FirstResult");
207+
_dialogHost.CurrentSession?.Close("SecondResult");
208+
object? result = await dialogTask;
209+
210+
Assert.Equal("SecondResult", result);
211+
Assert.Equal(2, closingInvokeCount);
212+
Assert.Equal(1, closedInvokeCount);
213+
}
214+
192215
[StaFact]
193216
[Description("Issue 1328")]
194217
public async Task WhenDoubleClickAwayDialogCloses()
@@ -256,6 +279,21 @@ public async Task WhenClosingDialogReturnValueCanBeSpecifiedInClosingEventHandle
256279
Assert.Equal(closeParameter, await showTask);
257280
}
258281

282+
[StaFact]
283+
public async Task WhenClosingDialogReturnValueCanBeSpecifiedInClosedEventHandler()
284+
{
285+
Guid closeParameter = Guid.NewGuid();
286+
287+
Task<object?> showTask = _dialogHost.ShowDialog("Content", (sender, args) => { }, (sender, args) => { }, (object sender, DialogClosedEventArgs args) =>
288+
{
289+
args.Session.CloseParameter = closeParameter;
290+
});
291+
292+
DialogHost.CloseDialogCommand.Execute(null, _dialogHost);
293+
294+
Assert.Equal(closeParameter, await showTask);
295+
}
296+
259297
[StaFact]
260298
[Description("Pull Request 2029")]
261299
public void WhenClosingDialogItThrowsWhenNoInstancesLoaded()
@@ -306,17 +344,25 @@ public void WhenClosingDialogWithParameterItPassesParameterToHandlers()
306344
{
307345
object parameter = Guid.NewGuid();
308346
object? closingParameter = null;
347+
object? closedParameter = null;
309348
_dialogHost.DialogClosing += DialogClosing;
349+
_dialogHost.DialogClosed += DialogClosed;
310350
_dialogHost.IsOpen = true;
311351

312352
DialogHost.Close(null, parameter);
313353

314354
Assert.Equal(parameter, closingParameter);
355+
Assert.Equal(parameter, closedParameter);
315356

316357
void DialogClosing(object sender, DialogClosingEventArgs eventArgs)
317358
{
318359
closingParameter = eventArgs.Parameter;
319360
}
361+
362+
void DialogClosed(object sender, DialogClosedEventArgs eventArgs)
363+
{
364+
closedParameter = eventArgs.Parameter;
365+
}
320366
}
321367

322368
[StaFact]
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
namespace MaterialDesignThemes.Wpf;
2+
3+
public class DialogClosedEventArgs : RoutedEventArgs
4+
{
5+
public DialogClosedEventArgs(DialogSession session, RoutedEvent routedEvent)
6+
: base(routedEvent)
7+
=> Session = session ?? throw new ArgumentNullException(nameof(session));
8+
9+
/// <summary>
10+
/// Gets the parameter originally provided to <see cref="DialogHost.CloseDialogCommand"/>/
11+
/// </summary>
12+
public object? Parameter => Session.CloseParameter;
13+
14+
/// <summary>
15+
/// Allows interaction with the current dialog session.
16+
/// </summary>
17+
public DialogSession Session { get; }
18+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
namespace MaterialDesignThemes.Wpf;
2+
3+
public delegate void DialogClosedEventHandler(object sender, DialogClosedEventArgs eventArgs);

0 commit comments

Comments
 (0)