diff --git a/src/MahApps.Metro.Samples/MahApps.Metro.Demo/ExampleViews/SplitViewExamples.xaml b/src/MahApps.Metro.Samples/MahApps.Metro.Demo/ExampleViews/SplitViewExamples.xaml index 47323525c0..6eed529d6d 100644 --- a/src/MahApps.Metro.Samples/MahApps.Metro.Demo/ExampleViews/SplitViewExamples.xaml +++ b/src/MahApps.Metro.Samples/MahApps.Metro.Demo/ExampleViews/SplitViewExamples.xaml @@ -117,13 +117,15 @@ - + + + + diff --git a/src/MahApps.Metro/Controls/SplitView/SplitView.cs b/src/MahApps.Metro/Controls/SplitView/SplitView.cs index 775ba2689a..f745fecd3e 100644 --- a/src/MahApps.Metro/Controls/SplitView/SplitView.cs +++ b/src/MahApps.Metro/Controls/SplitView/SplitView.cs @@ -4,6 +4,7 @@ using System; using System.Collections; +using System.ComponentModel; using System.Windows; using System.Windows.Controls; using System.Windows.Input; @@ -33,7 +34,7 @@ namespace MahApps.Metro.Controls [TemplateVisualState(Name = "OpenCompactOverlayRight", GroupName = "DisplayModeStates")] [ContentProperty(nameof(Content))] [StyleTypedProperty(Property = nameof(ResizeThumbStyle), StyleTargetType = typeof(MetroThumb))] - public class SplitView : Control + public class SplitView : ContentControl { private Rectangle? lightDismissLayer; private RectangleGeometry? paneClipRectangle; @@ -69,23 +70,6 @@ public double CompactPaneLength set => this.SetValue(CompactPaneLengthProperty, value); } - /// Identifies the dependency property. - public static readonly DependencyProperty ContentProperty - = DependencyProperty.Register(nameof(Content), - typeof(UIElement), - typeof(SplitView), - new PropertyMetadata(null)); - - /// - /// Gets or sets the contents of the main panel of a . - /// - /// The contents of the main panel of a . The default is null. - public UIElement? Content - { - get => (UIElement?)this.GetValue(ContentProperty); - set => this.SetValue(ContentProperty, value); - } - /// Identifies the dependency property. public static readonly DependencyProperty DisplayModeProperty = DependencyProperty.Register(nameof(DisplayMode), @@ -337,20 +321,87 @@ public Style? ResizeThumbStyle /// Identifies the dependency property. public static readonly DependencyProperty PaneProperty = DependencyProperty.Register(nameof(Pane), - typeof(UIElement), + typeof(object), typeof(SplitView), - new PropertyMetadata(null, UpdateLogicalChild)); + new FrameworkPropertyMetadata( + null, + new PropertyChangedCallback(OnPaneChanged))); /// /// Gets or sets the contents of the pane of a . /// /// The contents of the pane of a . The default is null. - public UIElement? Pane + [Bindable(true), Category("Content")] + public object? Pane { - get => (UIElement?)this.GetValue(PaneProperty); + get => this.GetValue(PaneProperty); set => this.SetValue(PaneProperty, value); } + /// + /// Called when PaneProperty is invalidated + /// + private static void OnPaneChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + SplitView splitView = (SplitView)d; + + splitView.OnPaneChanged(e.OldValue, e.NewValue); + } + + /// + /// This method is invoked when the Header property changes. + /// + /// The old value of the Header property. + /// The new value of the Header property. + protected virtual void OnPaneChanged(object oldPane, object newPane) + { + this.RemoveLogicalChild(oldPane); + this.AddLogicalChild(newPane); + + if (newPane is FrameworkElement frameworkElement) + { + frameworkElement.DataContext = this.DataContext; + } + } + + /// Identifies the dependency property. + public static readonly DependencyProperty PaneTemplateProperty + = DependencyProperty.Register( + nameof(PaneTemplate), + typeof(DataTemplate), + typeof(SplitView), + new FrameworkPropertyMetadata( + null, + new PropertyChangedCallback(OnPaneTemplateChanged))); + + /// + /// PaneTemplate is the template used to display the . + /// + [Bindable(true), Category("Content")] + public DataTemplate? PaneTemplate + { + get => (DataTemplate?)this.GetValue(PaneTemplateProperty); + set => this.SetValue(PaneTemplateProperty, value); + } + + /// + /// Called when PaneTemplateProperty is invalidated on "d." + /// + private static void OnPaneTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + SplitView ctrl = (SplitView)d; + ctrl.OnPaneTemplateChanged((DataTemplate?)e.OldValue, (DataTemplate?)e.NewValue); + } + + /// + /// This method is invoked when the PaneTemplate property changes. + /// + /// The old value of the PaneTemplate property. + /// The new value of the PaneTemplate property. + protected virtual void OnPaneTemplateChanged(DataTemplate? oldPaneTemplate, DataTemplate? newPaneTemplate) + { + } + /// Identifies the dependency property. public static readonly DependencyProperty PaneBackgroundProperty = DependencyProperty.Register(nameof(PaneBackground), @@ -504,25 +555,6 @@ private void ResizingThumb_DragDelta(object sender, System.Windows.Controls.Prim this.SetCurrentValue(OpenPaneLengthProperty, this.PanePlacement == SplitViewPanePlacement.Left ? this.OpenPaneLength + e.HorizontalChange : this.OpenPaneLength - e.HorizontalChange); } - private static void UpdateLogicalChild(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) - { - if (dependencyObject is not SplitView splitView) - { - return; - } - - if (e.OldValue is FrameworkElement oldChild) - { - splitView.RemoveLogicalChild(oldChild); - } - - if (e.NewValue is FrameworkElement newChild) - { - splitView.AddLogicalChild(newChild); - newChild.DataContext = splitView.DataContext; - } - } - /// protected override IEnumerator LogicalChildren {