12
12
13
13
namespace MaterialDesignThemes . Wpf
14
14
{
15
+ /// <summary>
16
+ /// Defines how a data context is sourced for a dialog if a <see cref="FrameworkElement"/>
17
+ /// is passed as the command parameter when using <see cref="DialogHost.OpenDialogCommand"/>.
18
+ /// </summary>
19
+ public enum DialogHostOpenDialogCommandDataContextSource
20
+ {
21
+ /// <summary>
22
+ /// The data context from the sender element (typically a <see cref="Button"/>)
23
+ /// is applied to the content.
24
+ /// </summary>
25
+ SenderElement ,
26
+ /// <summary>
27
+ /// The data context from the <see cref="DialogHost"/> is applied to the content.
28
+ /// </summary>
29
+ DialogHostInstance ,
30
+ /// <summary>
31
+ /// The data context is explicitly set to <c>null</c>.
32
+ /// </summary>
33
+ None
34
+ }
35
+
15
36
[ TemplatePart ( Name = PopupPartName , Type = typeof ( Popup ) ) ]
37
+ [ TemplatePart ( Name = PopupPartName , Type = typeof ( ContentControl ) ) ]
16
38
[ TemplateVisualState ( GroupName = "PopupStates" , Name = OpenStateName ) ]
17
39
[ TemplateVisualState ( GroupName = "PopupStates" , Name = ClosedStateName ) ]
18
40
public class DialogHost : ContentControl
19
41
{
20
42
public const string PopupPartName = "PART_Popup" ;
43
+ public const string PopupContentPartName = "PART_PopupContentElement" ;
21
44
public const string OpenStateName = "Open" ;
22
45
public const string ClosedStateName = "Closed" ;
23
46
@@ -37,6 +60,7 @@ public class DialogHost : ContentControl
37
60
private DialogClosingEventHandler _asyncShowClosingEventHandler ;
38
61
39
62
private Popup _popup ;
63
+ private ContentControl _popupContentControl ;
40
64
private DialogSession _session ;
41
65
private DialogOpenedEventHandler _attachedDialogOpenedEventHandler ;
42
66
private DialogClosingEventHandler _attachedDialogClosingEventHandler ;
@@ -276,9 +300,23 @@ public string DialogContentStringFormat
276
300
set { SetValue ( DialogContentStringFormatProperty , value ) ; }
277
301
}
278
302
303
+ public static readonly DependencyProperty OpenDialogCommandDataContextSourceProperty = DependencyProperty . Register (
304
+ "OpenDialogCommandDataContextSource" , typeof ( DialogHostOpenDialogCommandDataContextSource ) , typeof ( DialogHost ) , new PropertyMetadata ( default ( DialogHostOpenDialogCommandDataContextSource ) ) ) ;
305
+
306
+ /// <summary>
307
+ /// Defines how a data context is sourced for a dialog if a <see cref="FrameworkElement"/>
308
+ /// is passed as the command parameter when using <see cref="DialogHost.OpenDialogCommand"/>.
309
+ /// </summary>
310
+ public DialogHostOpenDialogCommandDataContextSource OpenDialogCommandDataContextSource
311
+ {
312
+ get { return ( DialogHostOpenDialogCommandDataContextSource ) GetValue ( OpenDialogCommandDataContextSourceProperty ) ; }
313
+ set { SetValue ( OpenDialogCommandDataContextSourceProperty , value ) ; }
314
+ }
315
+
279
316
public override void OnApplyTemplate ( )
280
317
{
281
- _popup = GetTemplateChild ( PopupPartName ) as Popup ;
318
+ _popup = GetTemplateChild ( PopupPartName ) as Popup ;
319
+ _popupContentControl = GetTemplateChild ( PopupContentPartName ) as ContentControl ;
282
320
283
321
VisualStateManager . GoToState ( this , SelectState ( ) , false ) ;
284
322
@@ -373,7 +411,7 @@ public static DialogClosingEventHandler GetDialogClosingAttached(DependencyObjec
373
411
}
374
412
375
413
public static readonly DependencyProperty DialogClosingCallbackProperty = DependencyProperty . Register (
376
- "DialogClosingCallback" , typeof ( DialogClosingEventHandler ) , typeof ( DialogHost ) , new PropertyMetadata ( default ( DialogClosingEventHandler ) ) ) ;
414
+ "DialogClosingCallback" , typeof ( DialogClosingEventHandler ) , typeof ( DialogHost ) , new PropertyMetadata ( default ( DialogClosingEventHandler ) ) ) ;
377
415
378
416
/// <summary>
379
417
/// Callback fired when the <see cref="DialogClosing"/> event is fired, allowing the event to be processed from a binding/view model.
@@ -438,19 +476,26 @@ private void OpenDialogHandler(object sender, ExecutedRoutedEventArgs executedRo
438
476
{
439
477
AssertTargetableContent ( ) ;
440
478
441
- //TODO enhancement: make the following configurable, so that the data context can be pulled from the dialog host if desired.
442
- // (leave the current behaviour as the default; most developers will find this logical, as the data context will "inherit" from button containing the content)
443
-
444
- var contentElement = executedRoutedEventArgs . Parameter as FrameworkElement ;
445
- var senderElement = executedRoutedEventArgs . OriginalSource as FrameworkElement ;
446
- if ( contentElement != null && senderElement != null && contentElement . DataContext == null && BindingOperations . GetBindingExpression ( contentElement , DataContextProperty ) == null )
479
+ if ( _popupContentControl != null )
447
480
{
448
- DialogContent = executedRoutedEventArgs . Parameter ;
449
- contentElement . SetCurrentValue ( DataContextProperty , senderElement . DataContext ) ;
481
+ switch ( OpenDialogCommandDataContextSource )
482
+ {
483
+ case DialogHostOpenDialogCommandDataContextSource . SenderElement :
484
+ _popupContentControl . DataContext =
485
+ ( executedRoutedEventArgs . Parameter as FrameworkElement ) ? . DataContext ;
486
+ break ;
487
+ case DialogHostOpenDialogCommandDataContextSource . DialogHostInstance :
488
+ _popupContentControl . DataContext = DataContext ;
489
+ break ;
490
+ case DialogHostOpenDialogCommandDataContextSource . None :
491
+ _popupContentControl . DataContext = null ;
492
+ break ;
493
+ default :
494
+ throw new ArgumentOutOfRangeException ( ) ;
495
+ }
450
496
}
451
- else
452
- DialogContent = executedRoutedEventArgs . Parameter ;
453
497
498
+ DialogContent = executedRoutedEventArgs . Parameter ;
454
499
}
455
500
456
501
SetCurrentValue ( IsOpenProperty , true ) ;
@@ -462,7 +507,7 @@ private void CloseDialogHandler(object sender, ExecutedRoutedEventArgs executedR
462
507
{
463
508
if ( executedRoutedEventArgs . Handled ) return ;
464
509
465
- Close ( executedRoutedEventArgs . Parameter ) ;
510
+ Close ( executedRoutedEventArgs . Parameter ) ;
466
511
467
512
executedRoutedEventArgs . Handled = true ;
468
513
}
0 commit comments