Skip to content

Commit

Permalink
Merge pull request #4471 from MahApps/fix/4468_splitview_bindings
Browse files Browse the repository at this point in the history
Change SplitView to ContentControl
  • Loading branch information
punker76 authored Mar 5, 2024
2 parents d432fcc + 0a940b4 commit 8f1d02b
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,15 @@
</mah:SplitView.Pane>

<Grid Background="CornflowerBlue">
<TextBlock Margin="20"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="20"
Foreground="White"
Text="This is the main content area and should be blue"
TextWrapping="Wrap" />
<StackPanel>
<TextBlock Margin="10"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
FontSize="20"
Foreground="Black"
Text="{Binding ElementName=sliderTest, Path=Value, Mode=OneWay, FallbackValue=0}" />
<Slider x:Name="sliderTest" Margin="10" Minimum="0" Maximum="100" Value="42" />
</StackPanel>
</Grid>

</mah:SplitView>
Expand Down
114 changes: 73 additions & 41 deletions src/MahApps.Metro/Controls/SplitView/SplitView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

using System;
using System.Collections;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -69,23 +70,6 @@ public double CompactPaneLength
set => this.SetValue(CompactPaneLengthProperty, value);
}

/// <summary>Identifies the <see cref="Content"/> dependency property.</summary>
public static readonly DependencyProperty ContentProperty
= DependencyProperty.Register(nameof(Content),
typeof(UIElement),
typeof(SplitView),
new PropertyMetadata(null));

/// <summary>
/// Gets or sets the contents of the main panel of a <see cref="SplitView" />.
/// </summary>
/// <returns>The contents of the main panel of a <see cref="SplitView" />. The default is null.</returns>
public UIElement? Content
{
get => (UIElement?)this.GetValue(ContentProperty);
set => this.SetValue(ContentProperty, value);
}

/// <summary>Identifies the <see cref="DisplayMode"/> dependency property.</summary>
public static readonly DependencyProperty DisplayModeProperty
= DependencyProperty.Register(nameof(DisplayMode),
Expand Down Expand Up @@ -337,20 +321,87 @@ public Style? ResizeThumbStyle
/// <summary>Identifies the <see cref="Pane"/> dependency property.</summary>
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)));

/// <summary>
/// Gets or sets the contents of the pane of a <see cref="SplitView" />.
/// </summary>
/// <returns>The contents of the pane of a <see cref="SplitView" />. The default is null.</returns>
public UIElement? Pane
[Bindable(true), Category("Content")]
public object? Pane
{
get => (UIElement?)this.GetValue(PaneProperty);
get => this.GetValue(PaneProperty);
set => this.SetValue(PaneProperty, value);
}

/// <summary>
/// Called when PaneProperty is invalidated
/// </summary>
private static void OnPaneChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
SplitView splitView = (SplitView)d;

splitView.OnPaneChanged(e.OldValue, e.NewValue);
}

/// <summary>
/// This method is invoked when the Header property changes.
/// </summary>
/// <param name="oldPane">The old value of the Header property.</param>
/// <param name="newPane">The new value of the Header property.</param>
protected virtual void OnPaneChanged(object oldPane, object newPane)
{
this.RemoveLogicalChild(oldPane);
this.AddLogicalChild(newPane);

if (newPane is FrameworkElement frameworkElement)
{
frameworkElement.DataContext = this.DataContext;
}
}

/// <summary>Identifies the <see cref="PaneTemplate"/> dependency property.</summary>
public static readonly DependencyProperty PaneTemplateProperty
= DependencyProperty.Register(
nameof(PaneTemplate),
typeof(DataTemplate),
typeof(SplitView),
new FrameworkPropertyMetadata(
null,
new PropertyChangedCallback(OnPaneTemplateChanged)));

/// <summary>
/// PaneTemplate is the template used to display the <seealso cref="Pane"/>.
/// </summary>
[Bindable(true), Category("Content")]
public DataTemplate? PaneTemplate
{
get => (DataTemplate?)this.GetValue(PaneTemplateProperty);
set => this.SetValue(PaneTemplateProperty, value);
}

/// <summary>
/// Called when PaneTemplateProperty is invalidated on "d."
/// </summary>
private static void OnPaneTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
SplitView ctrl = (SplitView)d;
ctrl.OnPaneTemplateChanged((DataTemplate?)e.OldValue, (DataTemplate?)e.NewValue);
}

/// <summary>
/// This method is invoked when the PaneTemplate property changes.
/// </summary>
/// <param name="oldPaneTemplate">The old value of the PaneTemplate property.</param>
/// <param name="newPaneTemplate">The new value of the PaneTemplate property.</param>
protected virtual void OnPaneTemplateChanged(DataTemplate? oldPaneTemplate, DataTemplate? newPaneTemplate)
{
}

/// <summary>Identifies the <see cref="PaneBackground"/> dependency property.</summary>
public static readonly DependencyProperty PaneBackgroundProperty
= DependencyProperty.Register(nameof(PaneBackground),
Expand Down Expand Up @@ -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;
}
}

/// <inheritdoc />
protected override IEnumerator LogicalChildren
{
Expand Down

0 comments on commit 8f1d02b

Please sign in to comment.