@@ -65,6 +65,8 @@ public class DialogHost : ContentControl
6565 private DialogOpenedEventHandler _attachedDialogOpenedEventHandler ;
6666 private DialogClosingEventHandler _attachedDialogClosingEventHandler ;
6767 private object _closeDialogExecutionParameter ;
68+ private IInputElement _restoreFocus ;
69+ private Action _closeCleanUp = ( ) => { } ;
6870
6971 static DialogHost ( )
7072 {
@@ -204,7 +206,7 @@ public DialogHost()
204206 Unloaded += OnUnloaded ;
205207
206208 CommandBindings . Add ( new CommandBinding ( CloseDialogCommand , CloseDialogHandler , CloseDialogCanExecute ) ) ;
207- CommandBindings . Add ( new CommandBinding ( OpenDialogCommand , OpenDialogHandler ) ) ;
209+ CommandBindings . Add ( new CommandBinding ( OpenDialogCommand , OpenDialogHandler ) ) ;
208210 }
209211
210212 public static readonly DependencyProperty IdentifierProperty = DependencyProperty . Register (
@@ -220,7 +222,7 @@ public object Identifier
220222 }
221223
222224 public static readonly DependencyProperty IsOpenProperty = DependencyProperty . Register (
223- "IsOpen" , typeof ( bool ) , typeof ( DialogHost ) , new FrameworkPropertyMetadata ( default ( bool ) , FrameworkPropertyMetadataOptions . BindsTwoWayByDefault , IsOpenPropertyChangedCallback ) ) ;
225+ "IsOpen" , typeof ( bool ) , typeof ( DialogHost ) , new FrameworkPropertyMetadata ( default ( bool ) , FrameworkPropertyMetadataOptions . BindsTwoWayByDefault , IsOpenPropertyChangedCallback ) ) ;
224226
225227 private static void IsOpenPropertyChangedCallback ( DependencyObject dependencyObject , DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs )
226228 {
@@ -229,12 +231,18 @@ private static void IsOpenPropertyChangedCallback(DependencyObject dependencyObj
229231 ValidationAssist . SetSuppress ( dialogHost . _popupContentControl , ! dialogHost . IsOpen ) ;
230232 VisualStateManager . GoToState ( dialogHost , dialogHost . SelectState ( ) , ! TransitionAssist . GetDisableTransitions ( dialogHost ) ) ;
231233
232- if ( ! dialogHost . IsOpen )
234+
235+ if ( dialogHost . IsOpen )
236+ {
237+ WatchWindowActivation ( dialogHost ) ;
238+ }
239+ else
233240 {
234241 dialogHost . _asyncShowWaitHandle . Set ( ) ;
235242 dialogHost . _attachedDialogClosingEventHandler = null ;
236243 dialogHost . _session . IsEnded = true ;
237244 dialogHost . _session = null ;
245+ dialogHost . _closeCleanUp ( ) ;
238246
239247 return ;
240248 }
@@ -265,7 +273,7 @@ private static void IsOpenPropertyChangedCallback(DependencyObject dependencyObj
265273 //totally not happy about this, but on immediate validation we can get some wierd looking stuff...give WPF a kick to refresh...
266274 Task . Delay ( 300 ) . ContinueWith ( t => child . Dispatcher . BeginInvoke ( new Action ( ( ) => child . InvalidateVisual ( ) ) ) ) ;
267275 } ) ) ;
268- }
276+ }
269277
270278 public bool IsOpen
271279 {
@@ -470,6 +478,14 @@ internal void Close(object parameter)
470478 _closeDialogExecutionParameter = parameter ;
471479 }
472480
481+ protected override void OnPreviewMouseDown ( MouseButtonEventArgs e )
482+ {
483+ var window = Window . GetWindow ( this ) ;
484+ if ( window != null && ! window . IsActive )
485+ window . Activate ( ) ;
486+ base . OnPreviewMouseDown ( e ) ;
487+ }
488+
473489 private void OpenDialogHandler ( object sender , ExecutedRoutedEventArgs executedRoutedEventArgs )
474490 {
475491 if ( executedRoutedEventArgs . Handled ) return ;
@@ -541,5 +557,38 @@ private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
541557 {
542558 LoadedInstances . Add ( this ) ;
543559 }
560+
561+ private static void WatchWindowActivation ( DialogHost dialogHost )
562+ {
563+ var window = Window . GetWindow ( dialogHost ) ;
564+ if ( window != null )
565+ {
566+ window . Activated += dialogHost . WindowOnActivated ;
567+ window . Deactivated += dialogHost . WindowOnDeactivated ;
568+ dialogHost . _closeCleanUp = ( ) =>
569+ {
570+ window . Activated -= dialogHost . WindowOnActivated ;
571+ window . Deactivated -= dialogHost . WindowOnDeactivated ;
572+ } ;
573+ }
574+ else
575+ {
576+ dialogHost . _closeCleanUp = ( ) => { } ;
577+ }
578+ }
579+
580+ private void WindowOnDeactivated ( object sender , EventArgs eventArgs )
581+ {
582+ _restoreFocus = _popupContentControl != null ? FocusManager . GetFocusedElement ( _popupContentControl ) : null ;
583+ }
584+
585+ private void WindowOnActivated ( object sender , EventArgs eventArgs )
586+ {
587+ if ( _restoreFocus != null )
588+ {
589+ Dispatcher . BeginInvoke ( new Action ( ( ) => Keyboard . Focus ( _restoreFocus ) ) ) ;
590+
591+ }
592+ }
544593 }
545594}
0 commit comments