1212
1313namespace MaterialDesignThemes . Wpf
1414{
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+
1536 [ TemplatePart ( Name = PopupPartName , Type = typeof ( Popup ) ) ]
37+ [ TemplatePart ( Name = PopupPartName , Type = typeof ( ContentControl ) ) ]
1638 [ TemplateVisualState ( GroupName = "PopupStates" , Name = OpenStateName ) ]
1739 [ TemplateVisualState ( GroupName = "PopupStates" , Name = ClosedStateName ) ]
1840 public class DialogHost : ContentControl
1941 {
2042 public const string PopupPartName = "PART_Popup" ;
43+ public const string PopupContentPartName = "PART_PopupContentElement" ;
2144 public const string OpenStateName = "Open" ;
2245 public const string ClosedStateName = "Closed" ;
2346
@@ -37,10 +60,11 @@ public class DialogHost : ContentControl
3760 private DialogClosingEventHandler _asyncShowClosingEventHandler ;
3861
3962 private Popup _popup ;
63+ private ContentControl _popupContentControl ;
64+ private DialogSession _session ;
4065 private DialogOpenedEventHandler _attachedDialogOpenedEventHandler ;
4166 private DialogClosingEventHandler _attachedDialogClosingEventHandler ;
4267 private object _closeDialogExecutionParameter ;
43- private DialogSession _session ;
4468
4569 static DialogHost ( )
4670 {
@@ -276,9 +300,23 @@ public string DialogContentStringFormat
276300 set { SetValue ( DialogContentStringFormatProperty , value ) ; }
277301 }
278302
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+
279316 public override void OnApplyTemplate ( )
280317 {
281- _popup = GetTemplateChild ( PopupPartName ) as Popup ;
318+ _popup = GetTemplateChild ( PopupPartName ) as Popup ;
319+ _popupContentControl = GetTemplateChild ( PopupContentPartName ) as ContentControl ;
282320
283321 VisualStateManager . GoToState ( this , SelectState ( ) , false ) ;
284322
@@ -373,7 +411,7 @@ public static DialogClosingEventHandler GetDialogClosingAttached(DependencyObjec
373411 }
374412
375413 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 ) ) ) ;
377415
378416 /// <summary>
379417 /// 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
438476 {
439477 AssertTargetableContent ( ) ;
440478
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 )
447480 {
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+ }
450496 }
451- else
452- DialogContent = executedRoutedEventArgs . Parameter ;
453497
498+ DialogContent = executedRoutedEventArgs . Parameter ;
454499 }
455500
456501 SetCurrentValue ( IsOpenProperty , true ) ;
@@ -467,7 +512,7 @@ private void CloseDialogHandler(object sender, ExecutedRoutedEventArgs executedR
467512 {
468513 if ( executedRoutedEventArgs . Handled ) return ;
469514
470- Close ( executedRoutedEventArgs . Parameter ) ;
515+ Close ( executedRoutedEventArgs . Parameter ) ;
471516
472517 executedRoutedEventArgs . Handled = true ;
473518 }
0 commit comments