| 1 | using System; |
| 2 | using System.Collections.Generic; |
| 3 | using System.Diagnostics; |
| 4 | using System.Linq; |
| 5 | using System.Text; |
| 6 | using System.Threading.Tasks; |
| 7 | using System.Windows; |
| 8 | using System.Windows.Controls; |
| 9 | using System.Windows.Input; |
| 10 | using System.Windows.Media.Animation; |
| 11 | using UI.Controls.Button; |
| 12 | using UI.Controls.Input; |
| 13 | using UI.Controls.SettingPanel; |
| 14 | |
| 15 | namespace UI.Controls.Expander |
| 16 | { |
| 17 | public class Expander : System.Windows.Controls.Expander |
| 18 | { |
| 19 | ///<summary> |
| 20 | /// |
| 21 | ///</summary> |
| 22 | public CornerRadius CornerRadius |
| 23 | { |
| 24 | get { return (CornerRadius)GetValue(CornerRadiusProperty); } |
| 25 | set { SetValue(CornerRadiusProperty, value); } |
| 26 | } |
| 27 | public static readonly DependencyProperty CornerRadiusProperty = |
| 28 | DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(Expander)); |
| 29 | |
| 30 | public Command ExpanderCommand { get; set; } |
| 31 | private Border HeaderBorder_; |
| 32 | private IconButton ExpBtn_; |
| 33 | |
| 34 | private Canvas ContentHeightCanvas_; |
| 35 | |
| 36 | private Border ContentBorder_; |
| 37 | private StackPanel ContentStackPanel_; |
| 38 | |
| 39 | |
| 40 | private Storyboard storyboard; |
| 41 | private DoubleAnimation expandTTFDoubleAnimation; |
| 42 | private DoubleAnimation expandHeightDoubleAnimation; |
| 43 | |
| 44 | public Expander() |
| 45 | { |
| 46 | DefaultStyleKey = typeof(Expander); |
| 47 | ExpanderCommand = new Command(new Action<object>(OnExpanderCommand)); |
| 48 | Loaded += Expander_Loaded; |
| 49 | } |
| 50 | |
| 51 | private void Expander_Loaded(object sender, RoutedEventArgs e) |
| 52 | { |
| 53 | ContentHeightCanvas_.SetValue(HeightProperty, ContentStackPanel_.ActualHeight); |
| 54 | ContentStackPanel_.SizeChanged += ContentStackPanel__SizeChanged; |
| 55 | |
| 56 | } |
| 57 | |
| 58 | private void CreateAnimations() |
| 59 | { |
| 60 | storyboard = new Storyboard(); |
| 61 | expandTTFDoubleAnimation = new DoubleAnimation(); |
| 62 | expandTTFDoubleAnimation.EasingFunction = new CubicEase() { EasingMode = EasingMode.EaseOut }; |
| 63 | Storyboard.SetTarget(expandTTFDoubleAnimation, ContentBorder_); |
| 64 | Storyboard.SetTargetProperty(expandTTFDoubleAnimation, new PropertyPath("(Border.RenderTransform).(TranslateTransform.Y)")); |
| 65 | |
| 66 | expandHeightDoubleAnimation = new DoubleAnimation(); |
| 67 | expandHeightDoubleAnimation.EasingFunction = new CubicEase() { EasingMode = EasingMode.EaseOut }; |
| 68 | Storyboard.SetTarget(expandHeightDoubleAnimation, ContentHeightCanvas_); |
| 69 | Storyboard.SetTargetProperty(expandHeightDoubleAnimation, new PropertyPath("(Canvas.Height)")); |
| 70 | |
| 71 | |
| 72 | storyboard.Children.Add(expandTTFDoubleAnimation); |
| 73 | storyboard.Children.Add(expandHeightDoubleAnimation); |
| 74 | |
| 75 | storyboard.Completed += Storyboard_Completed; |
| 76 | } |
| 77 | |
| 78 | private void Storyboard_Completed(object sender, EventArgs e) |
| 79 | { |
| 80 | ContentStackPanel_.SizeChanged -= ContentStackPanel__SizeChanged; |
| 81 | |
| 82 | if (IsExpanded) |
| 83 | { |
| 84 | ContentStackPanel_.SizeChanged += ContentStackPanel__SizeChanged; |
| 85 | } |
| 86 | } |
| 87 | |
| 88 | private void ContentStackPanel__SizeChanged(object sender, SizeChangedEventArgs e) |
| 89 | { |
| 90 | OnExpand(false); |
| 91 | } |
| 92 | |
| 93 | private void OnExpanderCommand(object obj) |
| 94 | { |
| 95 | IsExpanded = !IsExpanded; |
| 96 | OnExpand(); |
| 97 | } |
| 98 | |
| 99 | private void OnExpand(bool isAnimation = true) |
| 100 | { |
| 101 | |
| 102 | if (IsExpanded) |
| 103 | { |
| 104 | expandTTFDoubleAnimation.From = -ContentStackPanel_.ActualHeight; |
| 105 | expandTTFDoubleAnimation.To = 0; |
| 106 | |
| 107 | expandHeightDoubleAnimation.From = 0; |
| 108 | expandHeightDoubleAnimation.To = ContentStackPanel_.ActualHeight; |
| 109 | } |
| 110 | else |
| 111 | { |
| 112 | expandTTFDoubleAnimation.From = 0; |
| 113 | expandTTFDoubleAnimation.To = -ContentStackPanel_.ActualHeight; |
| 114 | |
| 115 | expandHeightDoubleAnimation.From = ContentStackPanel_.ActualHeight; |
| 116 | expandHeightDoubleAnimation.To = 0; |
| 117 | } |
| 118 | |
| 119 | if (!isAnimation) |
| 120 | { |
| 121 | expandTTFDoubleAnimation.Duration = new Duration(TimeSpan.Zero); |
| 122 | expandHeightDoubleAnimation.Duration = new Duration(TimeSpan.Zero); |
| 123 | } |
| 124 | else |
| 125 | { |
| 126 | expandTTFDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(.3)); |
| 127 | expandHeightDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(.25)); |
| 128 | } |
| 129 | storyboard.Begin(); |
| 130 | } |
| 131 | |
| 132 | public override void OnApplyTemplate() |
| 133 | { |
| 134 | base.OnApplyTemplate(); |
| 135 | HeaderBorder_ = GetTemplateChild("HeaderBorder") as Border; |
| 136 | ExpBtn_ = GetTemplateChild("ExpBtn") as IconButton; |
| 137 | ContentHeightCanvas_ = GetTemplateChild("ContentHeight") as Canvas; |
| 138 | ContentBorder_ = GetTemplateChild("Content") as Border; |
| 139 | ContentStackPanel_ = GetTemplateChild("ContentStackPanel") as StackPanel; |
| 140 | |
| 141 | CreateAnimations(); |
| 142 | HandleEvent(); |
| 143 | } |
| 144 | |
| 145 | private void HandleEvent() |
| 146 | { |
| 147 | if (HeaderBorder_ != null) |
| 148 | { |
| 149 | HeaderBorder_.MouseEnter += HeaderBorder__MouseEnter; |
| 150 | HeaderBorder_.MouseLeave += HeaderBorder__MouseLeave; |
| 151 | HeaderBorder_.MouseLeftButtonDown += HeaderBorder__MouseLeftButtonDown; |
| 152 | HeaderBorder_.MouseLeftButtonUp += HeaderBorder__MouseLeftButtonUp; |
| 153 | } |
| 154 | |
| 155 | if(ExpBtn_!= null) |
| 156 | { |
| 157 | ExpBtn_.MouseLeftButtonUp += ExpBtn__MouseLeftButtonUp; ; |
| 158 | } |
| 159 | |
| 160 | } |
| 161 | |
| 162 | private void ExpBtn__MouseLeftButtonUp(object sender, MouseButtonEventArgs e) |
| 163 | { |
| 164 | e.Handled = true; |
| 165 | } |
| 166 | |
| 167 | private void HeaderBorder__MouseLeftButtonUp(object sender, MouseButtonEventArgs e) |
| 168 | { |
| 169 | ExpBtn_.RaiseEvent(e); |
| 170 | } |
| 171 | |
| 172 | private void HeaderBorder__MouseLeftButtonDown(object sender, MouseButtonEventArgs e) |
| 173 | { |
| 174 | ExpBtn_.RaiseEvent(e); |
| 175 | } |
| 176 | |
| 177 | private void HeaderBorder__MouseLeave(object sender, MouseEventArgs e) |
| 178 | { |
| 179 | ExpBtn_.RaiseEvent(e); |
| 180 | } |
| 181 | |
| 182 | private void HeaderBorder__MouseEnter(object sender, System.Windows.Input.MouseEventArgs e) |
| 183 | { |
| 184 | ExpBtn_.RaiseEvent(e); |
| 185 | } |
| 186 | } |
| 187 | } |