Skip to content

Commit

Permalink
Fixes #263 by introducing ParentBackstage to BackstageTabControl
Browse files Browse the repository at this point in the history
  • Loading branch information
batzen committed Feb 4, 2016
1 parent 410d667 commit 72e8de8
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 29 deletions.
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
- [#254](../../issues/254) - Basic fix for KeyTips not working when focus is inside a WinForms control
- [#256](../../issues/256) - ComboBox items don't update properly on ItemsSource binding source collection changes
- [#257](../../issues/257) - Windows8 RibbonWindowTitleTextGlowBackground was missing
- [#263](../../issues/263) - Changing theme from backstage is broken
- OpenBackstage command was not acting on the correct backstage in a multiple backstage scenario (thanks to @maurosampietro)

- ### Enhancements
Expand Down
46 changes: 44 additions & 2 deletions Fluent.Ribbon.Showcase/TestContent.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,47 @@
</Fluent:BackstageTabItem.ContentTemplate>
</Fluent:BackstageTabItem>

<Fluent:BackstageTabItem Header="Change theme with fluent controls"
Content="Hello">
<Fluent:BackstageTabItem.ContentTemplate>
<DataTemplate>
<StackPanel>
<Fluent:Button Background="Blue"
Foreground="Black"
Click="OnOffice2010SilverClick">Office 2010 Silver</Fluent:Button>
<Fluent:Button Background="Blue"
Foreground="Black"
Click="OnOffice2010BlackClick">Office 2010 Black</Fluent:Button>
<Fluent:Button Background="Blue"
Foreground="Black"
Click="OnOffice2010BlueClick">Office 2010 Blue</Fluent:Button>
<Fluent:Button Background="Blue"
Foreground="Black"
Click="OnOffice2013Click">Office 2013 White</Fluent:Button>
<Fluent:Button Background="Blue"
Foreground="Black"
Click="OnWindows8Click">Windows8 White</Fluent:Button>
</StackPanel>
</DataTemplate>
</Fluent:BackstageTabItem.ContentTemplate>
</Fluent:BackstageTabItem>

<Fluent:BackstageTabItem Header="Change theme with standard controls"
Content="Hello">
<Fluent:BackstageTabItem.ContentTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Fluent:BackstageTabControl}}, Path=ParentBackstage.ActualHeight}" />
<Button Click="OnOffice2010SilverClick">Office 2010 Silver</Button>
<Button Click="OnOffice2010BlackClick">Office 2010 Black</Button>
<Button Click="OnOffice2010BlueClick">Office 2010 Blue</Button>
<Button Click="OnOffice2013Click">Office 2013 White</Button>
<Button Click="OnWindows8Click">Windows8 White</Button>
</StackPanel>
</DataTemplate>
</Fluent:BackstageTabItem.ContentTemplate>
</Fluent:BackstageTabItem>

<Fluent:SeparatorTabItem Header="Separator" />

<Fluent:BackstageTabItem Header="Info"
Expand Down Expand Up @@ -199,6 +240,7 @@
</Fluent:BackstageTabItem>

<Fluent:SeparatorTabItem />

<Fluent:BackstageTabItem Header="New"
KeyTip="N">
<Grid Margin="50"
Expand Down Expand Up @@ -242,12 +284,14 @@
ValueChanged="OnSpinnerValueChanged" />
</Grid>
</Fluent:BackstageTabItem>

<Fluent:BackstageTabItem Header="Print"
KeyTip="P">
<Grid Background="Yellow"
Opacity="0.3"
Margin="50" />
</Fluent:BackstageTabItem>

<Fluent:Button Header="Exit"
Icon="pack://application:,,,/Fluent.Ribbon.Showcase;component/Images/Exit.png"
KeyTip="X"
Expand Down Expand Up @@ -378,8 +422,6 @@
IsChecked="True" />
<Fluent:QuickAccessMenuItem IsChecked="True"
Target="{Binding ElementName=UndoButton}" />
<Fluent:QuickAccessMenuItem IsChecked="True"
Target="{Binding ElementName=RedoButton}" />
</Fluent:Ribbon.QuickAccessItems>

<Fluent:RibbonTabItem x:Name="homeTabItem"
Expand Down
36 changes: 34 additions & 2 deletions Fluent.Ribbon/Controls/BackstageTabControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

namespace Fluent
{
using Fluent.Internal;

/// <summary>
/// Represents Backstage tab control.
/// </summary>
Expand Down Expand Up @@ -189,6 +191,23 @@ public Brush ItemsPanelBackground

#endregion

/// <summary>
/// Gets or sets the <see cref="ParentBackstage"/>
/// </summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Backstage ParentBackstage
{
get { return (Backstage)this.GetValue(ParentBackstageProperty); }
set { this.SetValue(ParentBackstageProperty, value); }
}

/// <summary>
/// <see cref="DependencyProperty"/> for <see cref="ParentBackstage"/>
/// </summary>
public static readonly DependencyProperty ParentBackstageProperty =
DependencyProperty.Register(nameof(ParentBackstage), typeof(Backstage), typeof(BackstageTabControl), new PropertyMetadata(null));

#endregion

#region Constructors
Expand All @@ -200,11 +219,11 @@ public Brush ItemsPanelBackground
static BackstageTabControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(BackstageTabControl), new FrameworkPropertyMetadata(typeof(BackstageTabControl)));
StyleProperty.OverrideMetadata(typeof(BackstageTabControl), new FrameworkPropertyMetadata(null, new CoerceValueCallback(OnCoerceStyle)));
StyleProperty.OverrideMetadata(typeof(BackstageTabControl), new FrameworkPropertyMetadata(null, OnCoerceStyle));
}

// Coerce object style
static object OnCoerceStyle(DependencyObject d, object basevalue)
private static object OnCoerceStyle(DependencyObject d, object basevalue)
{
if (basevalue == null)
{
Expand All @@ -227,6 +246,19 @@ public BackstageTabControl()
HasDropShadow = false
};
this.ContextMenu.Opened += delegate { this.ContextMenu.IsOpen = false; };

this.Loaded += this.HandleLoaded;
this.Unloaded += this.HandleUnloaded;
}

private void HandleLoaded(object sender, RoutedEventArgs e)
{
this.ParentBackstage = UIHelper.GetParent<Backstage>(this);
}

private void HandleUnloaded(object sender, RoutedEventArgs e)
{
this.ParentBackstage = null;
}

#endregion
Expand Down
34 changes: 34 additions & 0 deletions Fluent.Ribbon/Internal/UIHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ public static TChildItem FindVisualChild<TChildItem>(DependencyObject parent) wh
return null;
}

/// <summary>
/// Gets all visual children of <paramref name="parent"/>.
/// </summary>
/// <returns></returns>
public static IEnumerable<DependencyObject> GetVisualChildren(DependencyObject parent)
{
var visualChildrenCount = VisualTreeHelper.GetChildrenCount(parent);
Expand All @@ -74,5 +78,35 @@ public static IEnumerable<DependencyObject> GetVisualChildren(DependencyObject p
}
}
}

/// <summary>
/// Finds the parent control of type <typeparamref name="T"/>.
/// First looks at the visual tree and then at the logical tree to find the parent.
/// </summary>
/// <returns>The found visual/logical parent or null.</returns>
public static T GetParent<T>(DependencyObject element)
where T : DependencyObject
{
var item = element;

while (item != null
&& item is T == false)
{
item = VisualTreeHelper.GetParent(item);
}

if (item == null)
{
item = element;

while (item != null &&
item is T == false)
{
item = LogicalTreeHelper.GetParent(item);
}
}

return (T)item;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Fluent="clr-namespace:Fluent"
xmlns:Fluent="clr-namespace:Fluent"
xmlns:Converters="clr-namespace:Fluent.Converters">
<ControlTemplate x:Key="BackstageButtonControlTemplate"
TargetType="{x:Type Fluent:Button}">
Expand Down Expand Up @@ -71,7 +71,7 @@
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>

<Style x:Key="BackstageButtonStyle"
TargetType="{x:Type Fluent:Button}">
<Setter Property="FocusVisualStyle"
Expand All @@ -87,7 +87,7 @@
<Setter Property="Foreground"
Value="{DynamicResource BackstageFontBrush}" />
</Style>

<Style TargetType="{x:Type Fluent:SeparatorTabItem}"
x:Key="BackstageSeparatorTabItemStyle">
<Setter Property="Template">
Expand Down Expand Up @@ -253,28 +253,28 @@
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>

<Style x:Key="BackstageStyle"
TargetType="{x:Type Fluent:BackstageTabControl}">
<Setter Property="OverridesDefaultStyle"
Value="True" />
Value="True" />
<Setter Property="Foreground"
Value="{DynamicResource DefaultFontBrush}" />
<Setter Property="Template"
Value="{DynamicResource BackstageControlTemplate}" />
<Setter Property="FocusVisualStyle"
Value="{DynamicResource ControlStyleEmptyFocus}" />
<Setter Property="Background"
Value="{Binding Background, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Fluent:Backstage}}, FallbackValue=Red}" />
Value="{Binding ParentBackstage.Background, RelativeSource={RelativeSource Self}, FallbackValue=Red}" />
<Setter Property="ItemsPanelBackground"
Value="{DynamicResource BackstagePanelBackgroundBrush}" />
<Setter Property="Margin">
<Setter.Value>
<MultiBinding Converter="{x:Static Converters:StaticConverters.ThicknessConverter}"
ConverterParameter="0 0 0 0">
<Binding Source="0" />
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type Fluent:Backstage}}"
Path="ActualHeight" />
<Binding RelativeSource="{RelativeSource Self}"
Path="ParentBackstage.ActualHeight" />
<Binding Source="0" />
<Binding Source="0" />
</MultiBinding>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,9 +245,9 @@
<ControlTemplate.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsOpen, RelativeSource={RelativeSource AncestorType={x:Type Fluent:Backstage}}}"
<Condition Binding="{Binding ParentBackstage.IsOpen, RelativeSource={RelativeSource Self}}"
Value="True" />
<Condition Binding="{Binding IsOpenAnimationEnabled, RelativeSource={RelativeSource AncestorType={x:Type Fluent:Backstage}}}"
<Condition Binding="{Binding ParentBackstage.IsOpenAnimationEnabled, RelativeSource={RelativeSource Self}}"
Value="True" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
Expand All @@ -260,19 +260,19 @@
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsOpen, RelativeSource={RelativeSource AncestorType={x:Type Fluent:Backstage}}}"
<Condition Binding="{Binding ParentBackstage.IsOpen, RelativeSource={RelativeSource Self}}"
Value="False" />
<Condition Binding="{Binding IsOpenAnimationEnabled, RelativeSource={RelativeSource AncestorType={x:Type Fluent:Backstage}}}"
<Condition Binding="{Binding ParentBackstage.IsOpenAnimationEnabled, RelativeSource={RelativeSource Self}}"
Value="True" />
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard x:Name="IsClosedBeginStoryboard"
Storyboard="{StaticResource OnIsOpenFalseStoryboard}" />
</MultiDataTrigger.EnterActions>
<MultiDataTrigger.ExitActions>
<RemoveStoryboard BeginStoryboardName="IsClosedBeginStoryboard" />
</MultiDataTrigger.ExitActions>
</MultiDataTrigger>
</MultiDataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>

Expand All @@ -287,7 +287,7 @@
<Setter Property="FocusVisualStyle"
Value="{DynamicResource ControlStyleEmptyFocus}" />
<Setter Property="Background"
Value="{Binding Background, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Fluent:Backstage}}, FallbackValue=Red}" />
Value="{Binding ParentBackstage.Background, RelativeSource={RelativeSource Self}, FallbackValue=Red}" />
<Setter Property="ItemsPanelBackground"
Value="{DynamicResource BackstagePanelBackgroundBrush}" />
</Style>
Expand Down
19 changes: 9 additions & 10 deletions Fluent.Ribbon/Themes/Windows8/Controls/BackstageTabControl.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>

<Style x:Key="BackstageButtonStyle"
TargetType="{x:Type Fluent:Button}">
<Setter Property="FocusVisualStyle"
Expand All @@ -87,7 +87,7 @@
<Setter Property="Foreground"
Value="{DynamicResource BackstageFontBrush}" />
</Style>

<Style TargetType="{x:Type Fluent:SeparatorTabItem}"
x:Key="BackstageSeparatorTabItemStyle">
<Setter Property="Template">
Expand Down Expand Up @@ -138,8 +138,7 @@
TargetType="{x:Type Fluent:Button}"
BasedOn="{StaticResource BackstageButtonStyle}" />
<Style x:Key="{x:Type ScrollBar}"
TargetType="{x:Type ScrollBar}"
/>
TargetType="{x:Type ScrollBar}" />
<Style x:Key="{x:Type Fluent:DropDownButton}"
TargetType="{x:Type Fluent:DropDownButton}"
BasedOn="{StaticResource DropDownButtonBackstageStyle}" />
Expand Down Expand Up @@ -251,31 +250,31 @@
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>

<Style x:Key="BackstageStyle"
TargetType="{x:Type Fluent:BackstageTabControl}">
<Setter Property="OverridesDefaultStyle"
Value="True" />
Value="True" />
<Setter Property="Foreground"
Value="{DynamicResource DefaultFontBrush}" />
<Setter Property="Template"
Value="{DynamicResource BackstageControlTemplate}" />
<Setter Property="FocusVisualStyle"
Value="{DynamicResource ControlStyleEmptyFocus}" />
<Setter Property="Background"
Value="{Binding Background, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Fluent:Backstage}}, FallbackValue=Red}" />
Value="{Binding ParentBackstage.Background, RelativeSource={RelativeSource Self}, FallbackValue=Red}" />
<Setter Property="ItemsPanelBackground"
Value="{DynamicResource BackstagePanelBackgroundBrush}" />
<Setter Property="Margin">
<Setter.Value>
<MultiBinding Converter="{x:Static Converters:StaticConverters.ThicknessConverter}"
ConverterParameter="0 0 0 0">
<Binding Source="0" />
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type Fluent:Backstage}}"
Path="ActualHeight" />
<Binding RelativeSource="{RelativeSource Self}"
Path="ParentBackstage.ActualHeight" />
<Binding Source="0" />
<Binding Source="0" />
</MultiBinding>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
Expand Down

0 comments on commit 72e8de8

Please sign in to comment.