Ribbon IsDropDownOpen prop support for animation

This commit is contained in:
NaBian committed 2022-06-13 23:06:48 +08:00
1 parent 2cd530c467
commit 1e07220d47
5 files changed
+116 -34

No files matched your search

@@ -0,0 +1,29 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using HandyControl.Data;
namespace HandyControl.Controls
{
public class ClipGrid : Grid
{
public static readonly DependencyProperty IsClipEnabledProperty = DependencyProperty.Register(
"IsClipEnabled", typeof(bool), typeof(ClipGrid), new PropertyMetadata(ValueBoxes.TrueBox));
public bool IsClipEnabled
{
get => (bool) GetValue(IsClipEnabledProperty);
set => SetValue(IsClipEnabledProperty, ValueBoxes.BooleanBox(value));
}
protected override Geometry GetLayoutClip(Size layoutSlotSize)
{
if (IsClipEnabled)
{
return base.GetLayoutClip(layoutSlotSize);
}
return null;
}
}
}
@@ -5,20 +5,33 @@ using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media.Animation;
using HandyControl.Data;
using HandyControl.Interactivity;
namespace HandyControl.Controls
{
[TemplatePart(Name = TabHeaderItemsControl, Type = typeof(ItemsControl))]
[TemplatePart(Name = RootPanel, Type = typeof(Panel))]
[TemplatePart(Name = ContentPanel, Type = typeof(Panel))]
public class Ribbon : Selector
{
private const string TabHeaderItemsControl = "PART_TabHeaderItemsControl";
private const string RootPanel = "PART_RootPanel";
private const string ContentPanel = "PART_ContentPanel";
private ItemsControl _tabHeaderItemsControl;
private Panel _rootPanel;
private Panel _contentPanel;
private System.Windows.Window _window;
private double _originHeight;
private readonly ObservableCollection<object> _tabHeaderItemsSource = new();
internal ItemsControl RibbonTabHeaderItemsControl => _tabHeaderItemsControl;
@@ -45,7 +58,23 @@ namespace HandyControl.Controls
=> (Ribbon) element.GetValue(RibbonProperty);
public static readonly DependencyProperty IsDropDownOpenProperty = DependencyProperty.Register(
"IsDropDownOpen", typeof(bool), typeof(Ribbon), new PropertyMetadata(ValueBoxes.TrueBox));
"IsDropDownOpen", typeof(bool), typeof(Ribbon), new PropertyMetadata(ValueBoxes.TrueBox, OnIsDropDownOpenChanged));
private static void OnIsDropDownOpenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((Ribbon) d).OnIsDropDownOpenChanged((bool) e.NewValue);
}
private void OnIsDropDownOpenChanged(bool isDropDownOpen)
{
if (_contentPanel == null)
{
return;
}
var animation = isDropDownOpen ? CreateAnimation(0, ContentHeight) : CreateAnimation(ContentHeight, 0);
_contentPanel.BeginAnimation(HeightProperty, animation);
}
public bool IsDropDownOpen
{
@@ -54,7 +83,25 @@ namespace HandyControl.Controls
}
public static readonly DependencyProperty IsMinimizedProperty = DependencyProperty.Register(
"IsMinimized", typeof(bool), typeof(Ribbon), new PropertyMetadata(ValueBoxes.FalseBox));
"IsMinimized", typeof(bool), typeof(Ribbon), new PropertyMetadata(ValueBoxes.FalseBox, OnIsMinimizedChanged));
private static void OnIsMinimizedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((Ribbon) d).OnIsMinimizedChanged((bool) e.NewValue);
}
private void OnIsMinimizedChanged(bool isMinimized)
{
if (_tabHeaderItemsControl == null || _rootPanel == null)
{
return;
}
var animation = isMinimized
? CreateAnimation(_originHeight, _tabHeaderItemsControl.ActualHeight)
: CreateAnimation(_tabHeaderItemsControl.ActualHeight, _originHeight);
_rootPanel.BeginAnimation(HeightProperty, animation);
}
public bool IsMinimized
{
@@ -80,6 +127,21 @@ namespace HandyControl.Controls
{
_tabHeaderItemsControl.ItemsSource = _tabHeaderItemsSource;
}
_rootPanel = GetTemplateChild(RootPanel) as Panel;
_contentPanel = GetTemplateChild(ContentPanel) as Panel;
_originHeight = MeasureOverride(new Size(double.MaxValue, double.MaxValue)).Height;
if (IsMinimized)
{
_rootPanel.SetCurrentValue(HeightProperty, _tabHeaderItemsControl.ActualHeight);
}
if (!IsDropDownOpen)
{
_contentPanel.SetCurrentValue(HeightProperty, .0);
}
}
internal void ResetSelection()
@@ -208,8 +270,6 @@ namespace HandyControl.Controls
_window.PreviewMouseRightButtonDown += Window_PreviewMouseRightButtonDown;
_window.PreviewMouseRightButtonUp += Window_PreviewMouseRightButtonUp;
}
UpdateLayout();
}
private void Ribbon_Unloaded(object sender, RoutedEventArgs e)
@@ -273,6 +333,12 @@ namespace HandyControl.Controls
private void InitializeSelection()
{
if (!IsDropDownOpen)
{
SelectedIndex = -1;
return;
}
if (SelectedIndex >= 0 || Items.Count <= 0)
{
return;
@@ -316,5 +382,16 @@ namespace HandyControl.Controls
_tabHeaderItemsSource.RemoveAt(itemsCount);
}
}
private static DoubleAnimation CreateAnimation(double fromValue, double toValue, double milliseconds = 200)
{
return new(fromValue, toValue, new Duration(TimeSpan.FromMilliseconds(milliseconds)))
{
EasingFunction = new PowerEase
{
EasingMode = EasingMode.EaseInOut
}
};
}
}
}
@@ -1,11 +0,0 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace HandyControl.Controls
{
public class RibbonTabsPanel : Grid
{
protected override Geometry GetLayoutClip(Size layoutSlotSize) => null;
}
}
@@ -52,6 +52,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Poptip.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Watermark.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Panel\AxleCanvas.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Panel\ClipGrid.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Panel\FlexPanel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Panel\ElementGroup.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Panel\SimpleStackPanel.cs" />
@@ -78,7 +79,6 @@
<Compile Include="$(MSBuildThisFileDirectory)Controls\Ribbon\RibbonTabHeader.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Ribbon\RibbonTabHeaderItemsControl.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Ribbon\RibbonTabHeadersPanel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Ribbon\RibbonTabsPanel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Screenshot\Screenshot.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Sprite.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Block\ToggleBlock.cs" />
@@ -119,27 +119,22 @@
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="hc:Ribbon">
<hc:RibbonTabsPanel x:Name="TabsPanel">
<hc:ClipGrid x:Name="PART_RootPanel" IsClipEnabled="False">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid x:Name="MainContentGrid" Grid.Row="1" RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<TransformGroup>
<TranslateTransform/>
</TransformGroup>
</Grid.RenderTransform>
<Grid x:Name="PART_ContentPanel" Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Border Margin="10,0" Height="{TemplateBinding ContentHeight}" Grid.ColumnSpan="2" CornerRadius="{Binding Path=(hc:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Background="{DynamicResource RegionBrush}">
<Border Margin="10,0" VerticalAlignment="Bottom" Height="{TemplateBinding ContentHeight}" Grid.ColumnSpan="2" CornerRadius="{Binding Path=(hc:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Background="{DynamicResource RegionBrush}">
<Border.Effect>
<DropShadowEffect BlurRadius="8" ShadowDepth="2" Direction="-90" Color="{StaticResource EffectShadowColor}" Opacity=".1" RenderingBias="Performance"/>
</Border.Effect>
</Border>
<ItemsPresenter Grid.Column="0" Margin="10,0,0,0"/>
<ItemsPresenter VerticalAlignment="Bottom" Height="{TemplateBinding ContentHeight}" Grid.Column="0" Margin="10,0,0,0"/>
<ToggleButton Command="interactivity:ControlCommands.Switch" IsChecked="{Binding IsMinimized,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}" Margin="0,0,10,0" Padding="5" Width="20" Height="20" Grid.Column="1" HorizontalAlignment="Right" VerticalAlignment="Bottom" Style="{StaticResource ToggleButtonIconTransparent}" hc:IconElement.Geometry="{StaticResource UpGeometry}" hc:IconSwitchElement.GeometrySelected="{StaticResource NailGeometry}"/>
</Grid>
<hc:RibbonTabHeaderItemsControl Grid.Row="0" Background="{TemplateBinding Background}" Focusable="False" x:Name="PART_TabHeaderItemsControl" Margin="0,0,0,2">
@@ -149,15 +144,7 @@
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</hc:RibbonTabHeaderItemsControl>
</hc:RibbonTabsPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsMinimized" Value="True">
<Setter TargetName="TabsPanel" Property="Height" Value="{Binding ActualHeight,ElementName=PART_TabHeaderItemsControl}"/>
</Trigger>
<Trigger Property="IsDropDownOpen" Value="False">
<Setter TargetName="MainContentGrid" Property="Visibility" Value="Collapsed"/>
</Trigger>
</ControlTemplate.Triggers>
</hc:ClipGrid>
</ControlTemplate>
</Setter.Value>
</Setter>