diff --git a/docs/release-notes/1.5.0.md b/docs/release-notes/1.5.0.md
index 3c47770376..5edb81f527 100644
--- a/docs/release-notes/1.5.0.md
+++ b/docs/release-notes/1.5.0.md
@@ -17,7 +17,28 @@
- New `Badged` control. Thx to @ButchersBoy
![image](https://cloud.githubusercontent.com/assets/658431/23340345/d7dc4c86-fc34-11e6-838b-1ebee9381c7d.png)
- The `ControlsHelper.CornerRadius` can now used for `SplitButton` and `DropDownButton`.
-
+- New underline types for `TabControl` and `MetroTabControl` [#2902](https://github.com/MahApps/MahApps.Metro/pull/2902)
+ + Adds a new `Underlined` attached property to `TabControlHelper` which controls the type of the underline type. The old `IsUnderlined` property is now obsolete.
+ ```
+ ///
+ /// Specifies the underline position of a TabControl.
+ ///
+ public enum UnderlinedType
+ {
+ None, // nothing
+ TabItems, // the old behavior with `IsUnderlined="True"`
+ SelectedTabItem, // selected TabItem underlined + underline hover effect for unselected items
+ TabPanel // underlined TabPanel and selected/hovered TabItem
+ }
+ ```
+ + Add also new `Brush` attached properties to enable easy changing the underline brushes.
+ ```
+ TabControlHelper.UnderlineBrush
+ TabControlHelper.UnderlineSelectedBrush
+ TabControlHelper.UnderlineMouseOverBrush
+ TabControlHelper.UnderlineMouseOverSelectedBrush
+ ```
+ ![mahapps_newunderline4](https://cloud.githubusercontent.com/assets/658431/24204520/0e6f3cbc-0f19-11e7-8a2b-f40752918a96.gif)
## Closed Issues
@@ -33,3 +54,4 @@
- [#2792](https://github.com/MahApps/MahApps.Metro/issues/2792) Win32Exception on closing window
- [#2886](https://github.com/MahApps/MahApps.Metro/issues/2886) NumericUpDown: HasDecimals=False & using a bound StringFormat allows to enter a decimal point [@davericardo](https://github.com/davericardo)
- [#2885](https://github.com/MahApps/MahApps.Metro/issues/2885) [Bug] Badged Control Causes Window Loading to Hang
+- [#2895](https://github.com/MahApps/MahApps.Metro/issues/2895) [RFC] [Enhancement] Proposed TabControlHelper.IsUnderlined Change
diff --git a/src/MahApps.Metro.Samples/MahApps.Metro.Demo/MahApps.Metro.Demo.Shared/ExampleViews/TabControlExamples.xaml b/src/MahApps.Metro.Samples/MahApps.Metro.Demo/MahApps.Metro.Demo.Shared/ExampleViews/TabControlExamples.xaml
index 8fba7583e8..4292167335 100644
--- a/src/MahApps.Metro.Samples/MahApps.Metro.Demo/MahApps.Metro.Demo.Shared/ExampleViews/TabControlExamples.xaml
+++ b/src/MahApps.Metro.Samples/MahApps.Metro.Demo/MahApps.Metro.Demo.Shared/ExampleViews/TabControlExamples.xaml
@@ -10,12 +10,49 @@
d:DesignWidth="800"
d:DataContext="{d:DesignInstance MetroDemo:MainWindowViewModel}">
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
+
+
+
+
+
+
@@ -35,27 +72,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -75,6 +92,7 @@
+
@@ -97,50 +115,11 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
+
@@ -214,6 +193,7 @@
+
@@ -231,8 +211,9 @@
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
+
diff --git a/src/MahApps.Metro/MahApps.Metro.Shared/Controls/Helper/TabControlHelper.cs b/src/MahApps.Metro/MahApps.Metro.Shared/Controls/Helper/TabControlHelper.cs
index e99ac86aae..40f225ba38 100644
--- a/src/MahApps.Metro/MahApps.Metro.Shared/Controls/Helper/TabControlHelper.cs
+++ b/src/MahApps.Metro/MahApps.Metro.Shared/Controls/Helper/TabControlHelper.cs
@@ -1,36 +1,169 @@
-using System.Windows;
+using System;
+using System.ComponentModel;
+using System.Windows;
using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
+using System.Windows.Media;
namespace MahApps.Metro.Controls
{
- using System.ComponentModel;
+ ///
+ /// Specifies the underline position of a TabControl.
+ ///
+ public enum UnderlinedType
+ {
+ None,
+ TabItems,
+ SelectedTabItem,
+ TabPanel
+ }
public static class TabControlHelper
{
///
- /// Defines whether the underline below the is shown or not.
+ /// Defines whether the underline below the is shown or not.
///
+ [Obsolete(@"This property will be deleted in the next release. You should now use the Underlined attached property.")]
public static readonly DependencyProperty IsUnderlinedProperty =
- DependencyProperty.RegisterAttached("IsUnderlined", typeof(bool), typeof(TabControlHelper), new PropertyMetadata(false));
+ DependencyProperty.RegisterAttached("IsUnderlined",
+ typeof(bool),
+ typeof(TabControlHelper),
+ new PropertyMetadata(false,
+ (o, e) =>
+ {
+ var element = o as UIElement;
+ if (element != null && e.OldValue != e.NewValue && e.NewValue is bool)
+ {
+ TabControlHelper.SetUnderlined(element, (bool)e.NewValue ? UnderlinedType.TabItems : UnderlinedType.None);
+ }
+ }));
[Category(AppName.MahApps)]
[AttachedPropertyBrowsableForType(typeof(TabControl))]
- [AttachedPropertyBrowsableForType(typeof(TabItem))]
+ [Obsolete(@"This property will be deleted in the next release. You should now use the Underlined attached property.")]
public static bool GetIsUnderlined(UIElement element)
{
return (bool)element.GetValue(IsUnderlinedProperty);
}
+ [Obsolete(@"This property will be deleted in the next release. You should now use the Underlined attached property.")]
public static void SetIsUnderlined(UIElement element, bool value)
{
element.SetValue(IsUnderlinedProperty, value);
}
+ ///
+ /// Defines whether the underline below the or is shown or not.
+ ///
+ public static readonly DependencyProperty UnderlinedProperty =
+ DependencyProperty.RegisterAttached("Underlined",
+ typeof(UnderlinedType),
+ typeof(TabControlHelper),
+ new PropertyMetadata(UnderlinedType.None));
+
+ [Category(AppName.MahApps)]
+ [AttachedPropertyBrowsableForType(typeof(TabControl))]
+ public static UnderlinedType GetUnderlined(UIElement element)
+ {
+ return (UnderlinedType)element.GetValue(UnderlinedProperty);
+ }
+
+ public static void SetUnderlined(UIElement element, UnderlinedType value)
+ {
+ element.SetValue(UnderlinedProperty, value);
+ }
+
+ ///
+ /// Defines the underline brush below the or .
+ ///
+ public static readonly DependencyProperty UnderlineBrushProperty =
+ DependencyProperty.RegisterAttached("UnderlineBrush",
+ typeof(Brush),
+ typeof(TabControlHelper),
+ new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.SubPropertiesDoNotAffectRender));
+
+ [Category(AppName.MahApps)]
+ [AttachedPropertyBrowsableForType(typeof(TabControl))]
+ public static Brush GetUnderlineBrush(UIElement element)
+ {
+ return (Brush)element.GetValue(UnderlineBrushProperty);
+ }
+
+ public static void SetUnderlineBrush(UIElement element, Brush value)
+ {
+ element.SetValue(UnderlineBrushProperty, value);
+ }
+
+ ///
+ /// Defines the underline brush below the or of an selected item.
+ ///
+ public static readonly DependencyProperty UnderlineSelectedBrushProperty =
+ DependencyProperty.RegisterAttached("UnderlineSelectedBrush",
+ typeof(Brush),
+ typeof(TabControlHelper),
+ new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.SubPropertiesDoNotAffectRender));
+
+ [Category(AppName.MahApps)]
+ [AttachedPropertyBrowsableForType(typeof(TabControl))]
+ public static Brush GetUnderlineSelectedBrush(UIElement element)
+ {
+ return (Brush)element.GetValue(UnderlineSelectedBrushProperty);
+ }
+
+ public static void SetUnderlineSelectedBrush(UIElement element, Brush value)
+ {
+ element.SetValue(UnderlineSelectedBrushProperty, value);
+ }
+
+ ///
+ /// Defines the underline brush below the or if the mouse is over an item.
+ ///
+ public static readonly DependencyProperty UnderlineMouseOverBrushProperty =
+ DependencyProperty.RegisterAttached("UnderlineMouseOverBrush",
+ typeof(Brush),
+ typeof(TabControlHelper),
+ new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.SubPropertiesDoNotAffectRender));
+
+ [Category(AppName.MahApps)]
+ [AttachedPropertyBrowsableForType(typeof(TabControl))]
+ public static Brush GetUnderlineMouseOverBrush(UIElement element)
+ {
+ return (Brush)element.GetValue(UnderlineMouseOverBrushProperty);
+ }
+
+ public static void SetUnderlineMouseOverBrush(UIElement element, Brush value)
+ {
+ element.SetValue(UnderlineMouseOverBrushProperty, value);
+ }
+
+ ///
+ /// Defines the underline brush below the or if the mouse is over a selected item.
+ ///
+ public static readonly DependencyProperty UnderlineMouseOverSelectedBrushProperty =
+ DependencyProperty.RegisterAttached("UnderlineMouseOverSelectedBrush",
+ typeof(Brush),
+ typeof(TabControlHelper),
+ new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.SubPropertiesDoNotAffectRender));
+
+ [Category(AppName.MahApps)]
+ [AttachedPropertyBrowsableForType(typeof(TabControl))]
+ public static Brush GetUnderlineMouseOverSelectedBrush(UIElement element)
+ {
+ return (Brush)element.GetValue(UnderlineMouseOverSelectedBrushProperty);
+ }
+
+ public static void SetUnderlineMouseOverSelectedBrush(UIElement element, Brush value)
+ {
+ element.SetValue(UnderlineMouseOverSelectedBrushProperty, value);
+ }
+
///
/// This property can be used to set the Transition for animated TabControls
///
public static readonly DependencyProperty TransitionProperty =
- DependencyProperty.RegisterAttached("Transition", typeof(TransitionType), typeof(TabControlHelper),
+ DependencyProperty.RegisterAttached("Transition",
+ typeof(TransitionType),
+ typeof(TabControlHelper),
new FrameworkPropertyMetadata(TransitionType.Default, FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.Inherits));
[Category(AppName.MahApps)]
diff --git a/src/MahApps.Metro/MahApps.Metro.Shared/Controls/Underline.cs b/src/MahApps.Metro/MahApps.Metro.Shared/Controls/Underline.cs
new file mode 100644
index 0000000000..0b9d1c3e76
--- /dev/null
+++ b/src/MahApps.Metro/MahApps.Metro.Shared/Controls/Underline.cs
@@ -0,0 +1,96 @@
+using System;
+using System.Windows;
+using System.Windows.Controls;
+
+namespace MahApps.Metro.Controls
+{
+ [TemplatePart(Name = UnderlineBorderPartName, Type = typeof(Border))]
+ public class Underline : ContentControl
+ {
+ public const string UnderlineBorderPartName = "PART_UnderlineBorder";
+ private Border _underlineBorder;
+
+ public static readonly DependencyProperty PlacementProperty =
+ DependencyProperty.Register(nameof(Placement),
+ typeof(Dock),
+ typeof(Underline),
+ new PropertyMetadata(default(Dock), (o, e) => { (o as Underline)?.ApplyBorderProperties(); }));
+
+ public Dock Placement
+ {
+ get { return (Dock)this.GetValue(PlacementProperty); }
+ set { this.SetValue(PlacementProperty, value); }
+ }
+
+ public static readonly DependencyProperty LineThicknessProperty =
+ DependencyProperty.Register(nameof(LineThickness),
+ typeof(double),
+ typeof(Underline),
+ new PropertyMetadata(1d, (o, e) => { (o as Underline)?.ApplyBorderProperties(); }));
+
+ public double LineThickness
+ {
+ get { return (double)this.GetValue(LineThicknessProperty); }
+ set { this.SetValue(LineThicknessProperty, value); }
+ }
+
+ public static readonly DependencyProperty LineExtentProperty =
+ DependencyProperty.Register(nameof(LineExtent),
+ typeof(double),
+ typeof(Underline),
+ new PropertyMetadata(Double.NaN, (o, e) => { (o as Underline)?.ApplyBorderProperties(); }));
+
+ public double LineExtent
+ {
+ get { return (double)this.GetValue(LineExtentProperty); }
+ set { this.SetValue(LineExtentProperty, value); }
+ }
+
+ static Underline()
+ {
+ DefaultStyleKeyProperty.OverrideMetadata(typeof(Underline), new FrameworkPropertyMetadata(typeof(Underline)));
+ }
+
+ public override void OnApplyTemplate()
+ {
+ base.OnApplyTemplate();
+
+ this._underlineBorder = this.GetTemplateChild(UnderlineBorderPartName) as Border;
+ this.ApplyBorderProperties();
+ }
+
+ private void ApplyBorderProperties()
+ {
+ if (this._underlineBorder == null)
+ {
+ return;
+ }
+
+ this._underlineBorder.Height = Double.NaN;
+ this._underlineBorder.Width = Double.NaN;
+ this._underlineBorder.BorderThickness = new Thickness();
+ switch (this.Placement)
+ {
+ case Dock.Left:
+ this._underlineBorder.Width = this.LineExtent;
+ this._underlineBorder.BorderThickness = new Thickness(this.LineThickness, 0d, 0d, 0d);
+ break;
+ case Dock.Top:
+ this._underlineBorder.Height = this.LineExtent;
+ this._underlineBorder.BorderThickness = new Thickness(0d, this.LineThickness, 0d, 0d);
+ break;
+ case Dock.Right:
+ this._underlineBorder.Width = this.LineExtent;
+ this._underlineBorder.BorderThickness = new Thickness(0d, 0d, this.LineThickness, 0d);
+ break;
+ case Dock.Bottom:
+ this._underlineBorder.Height = this.LineExtent;
+ this._underlineBorder.BorderThickness = new Thickness(0d, 0d, 0d, this.LineThickness);
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ this.InvalidateVisual();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/MahApps.Metro/MahApps.Metro.Shared/MahApps.Metro.Shared.projitems b/src/MahApps.Metro/MahApps.Metro.Shared/MahApps.Metro.Shared.projitems
index 74abb43b7a..3347a1cc4e 100644
--- a/src/MahApps.Metro/MahApps.Metro.Shared/MahApps.Metro.Shared.projitems
+++ b/src/MahApps.Metro/MahApps.Metro.Shared/MahApps.Metro.Shared.projitems
@@ -131,6 +131,7 @@
+
diff --git a/src/MahApps.Metro/MahApps.Metro/MahApps.Metro.NET40.csproj b/src/MahApps.Metro/MahApps.Metro/MahApps.Metro.NET40.csproj
index 7143eeabcf..932b9090a6 100644
--- a/src/MahApps.Metro/MahApps.Metro/MahApps.Metro.NET40.csproj
+++ b/src/MahApps.Metro/MahApps.Metro/MahApps.Metro.NET40.csproj
@@ -536,6 +536,10 @@
MSBuild:Compile
Designer
+
+ MSBuild:Compile
+ Designer
+
MSBuild:Compile
Designer
diff --git a/src/MahApps.Metro/MahApps.Metro/MahApps.Metro.NET45.csproj b/src/MahApps.Metro/MahApps.Metro/MahApps.Metro.NET45.csproj
index eaa1bb456f..3898758e78 100644
--- a/src/MahApps.Metro/MahApps.Metro/MahApps.Metro.NET45.csproj
+++ b/src/MahApps.Metro/MahApps.Metro/MahApps.Metro.NET45.csproj
@@ -536,6 +536,10 @@
MSBuild:Compile
Designer
+
+ Designer
+ MSBuild:Compile
+
MSBuild:Compile
Designer
diff --git a/src/MahApps.Metro/MahApps.Metro/Styles/Controls.TabControl.xaml b/src/MahApps.Metro/MahApps.Metro/Styles/Controls.TabControl.xaml
index c7712af857..c3a20523af 100644
--- a/src/MahApps.Metro/MahApps.Metro/Styles/Controls.TabControl.xaml
+++ b/src/MahApps.Metro/MahApps.Metro/Styles/Controls.TabControl.xaml
@@ -5,7 +5,11 @@
+
+
\ No newline at end of file