跳到主要内容

github/tai

公开

Tai · Windows 软件与网站使用时长统计。上游 Planshit/Tai 的源码镜像,非灵栈原创;MIT 许可。来源:https://github.com/Planshit/Tai 。本次为手动同步,暂不提供安装包。

浏览文件

Tabbar.cs

246 行 · 8.0 KB历史下载
1using System;
2using System.Collections.Generic;
3using System.Collections.ObjectModel;
4using System.Collections.Specialized;
5using System.Diagnostics;
6using System.Linq;
7using System.Text;
8using System.Windows;
9using System.Windows.Controls;
10using System.Windows.Input;
11using System.Windows.Media;
12using System.Windows.Media.Animation;
13using UI.Controls.Navigation.Models;
14
15namespace UI.Controls.Tabbar
16{
17 public class Tabbar : Control
18 {
19
20 public Color SelectedTextColor
21 {
22 get { return (Color)GetValue(SelectedTextColorProperty); }
23 set { SetValue(SelectedTextColorProperty, value); }
24 }
25 public static readonly DependencyProperty SelectedTextColorProperty =
26 DependencyProperty.Register("SelectedTextColor", typeof(Color), typeof(Tabbar));
27 public int SelectedIndex
28 {
29 get { return (int)GetValue(SelectedIndexProperty); }
30 set { SetValue(SelectedIndexProperty, value); }
31 }
32 public static readonly DependencyProperty SelectedIndexProperty =
33 DependencyProperty.Register("SelectedIndex", typeof(int), typeof(Tabbar), new PropertyMetadata((int)0, new PropertyChangedCallback(OnSelectedItemChanged)));
34
35 private static void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
36 {
37 var control = d as Tabbar;
38 if (e.NewValue != e.OldValue)
39 {
40 control.ScrollToActive(int.Parse(e.OldValue.ToString()));
41 }
42 }
43
44
45 public ObservableCollection<string> Data
46 {
47 get
48 {
49 return (ObservableCollection<string>)GetValue(DataProperty);
50 }
51 set
52 {
53 SetValue(DataProperty, value);
54 }
55 }
56 public static readonly DependencyProperty DataProperty =
57 DependencyProperty.Register("Data", typeof(ObservableCollection<string>), typeof(Tabbar));
58
59
60 //private StackPanel ItemsPanel;
61 private List<TextBlock> ItemsDictionary;
62 private Grid ItemsContainer;
63 // 选中标记块
64 private Border ActiveBlock;
65 // 动画
66 Storyboard storyboard;
67 DoubleAnimation scrollAnimation;
68 ColorAnimation fontColorAnimation;
69 ColorAnimation oldFontColorAnimation;
70 public Tabbar()
71 {
72 DefaultStyleKey = typeof(Tabbar);
73 ItemsDictionary = new List<TextBlock>();
74 }
75
76
77
78 public override void OnApplyTemplate()
79 {
80 base.OnApplyTemplate();
81 //ItemsPanel = GetTemplateChild("ItemsPanel") as StackPanel;
82 ActiveBlock = GetTemplateChild("ActiveBlock") as Border;
83 ItemsContainer = GetTemplateChild("ItemsContainer") as Grid;
84
85 CreateAnimations();
86 Render();
87 }
88
89
90 private void AddItem(string item, int col)
91 {
92 if (ItemsContainer != null)
93 {
94 var control = new TextBlock();
95 control.TextAlignment = TextAlignment.Center;
96 control.Text = item;
97 control.Margin = new Thickness(0, 0, 10, 0);
98 control.FontSize = 16;
99 control.Cursor = Cursors.Hand;
100 control.Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#1F1F1F"));
101 control.VerticalAlignment = VerticalAlignment.Bottom;
102 control.MouseUp += (e, c) =>
103 {
104 int index = Data.IndexOf(item);
105 if (SelectedIndex != index)
106 {
107 SelectedIndex = index;
108 }
109 };
110 if (Data.IndexOf(item) == Data.Count - 1)
111 {
112 control.Loaded += (e, c) =>
113 {
114 ActiveBlock.Width = control.ActualWidth;
115 ScrollToActive();
116 Reset();
117 };
118 }
119 Grid.SetColumn(control, col);
120 ItemsContainer.Children.Add(control);
121 ItemsDictionary.Add(control);
122 }
123 }
124
125
126
127 private void Render()
128 {
129 if (Data != null)
130 {
131 ItemsContainer.Children.Clear();
132 ItemsContainer.ColumnDefinitions.Clear();
133 ItemsDictionary.Clear();
134
135 for (int i = 0; i < Data.Count; i++)
136 {
137 var item = Data[i];
138
139 ItemsContainer.ColumnDefinitions.Add(new ColumnDefinition()
140 {
141 Width = new GridLength(1, GridUnitType.Star)
142 });
143
144 AddItem(item, i);
145
146 }
147 //foreach (var item in Data)
148 //{
149
150 // AddItem(item);
151 //}
152
153 }
154 }
155
156 #region create animations
157 private void CreateAnimations()
158 {
159 storyboard = new Storyboard();
160 scrollAnimation = new DoubleAnimation();
161 //scrollAnimation.EasingFunction = new BackEase() { EasingMode = EasingMode.EaseOut, Amplitude = .8 };
162 scrollAnimation.Duration = new Duration(TimeSpan.FromSeconds(0.1));
163
164 Storyboard.SetTarget(scrollAnimation, ActiveBlock);
165 Storyboard.SetTargetProperty(scrollAnimation, new PropertyPath("RenderTransform.Children[0].X"));
166
167
168
169
170 fontColorAnimation = new ColorAnimation();
171 //fontColorAnimation.EasingFunction = new SineEase() { EasingMode = EasingMode.EaseIn };
172 fontColorAnimation.Duration = new Duration(TimeSpan.FromSeconds(0.1));
173
174 Storyboard.SetTargetProperty(fontColorAnimation, new PropertyPath("(TextBlock.Foreground).(SolidColorBrush.Color)"));
175
176
177 oldFontColorAnimation = new ColorAnimation();
178 oldFontColorAnimation.To = (Color)ColorConverter.ConvertFromString("#CCCCCC");
179 oldFontColorAnimation.Duration = new Duration(TimeSpan.FromSeconds(0.3));
180
181 //oldFontColorAnimation.EasingFunction = new SineEase() { EasingMode = EasingMode.EaseIn };
182 Storyboard.SetTargetProperty(oldFontColorAnimation, new PropertyPath("(TextBlock.Foreground).(SolidColorBrush.Color)"));
183
184
185 //storyboard.Children.Add(oldFontColorAnimation);
186 storyboard.Children.Add(scrollAnimation);
187 storyboard.Children.Add(fontColorAnimation);
188
189 }
190 #endregion
191 private void ScrollToActive(int oldSelectedIndex = 0)
192 {
193 if (oldSelectedIndex > ItemsDictionary.Count || ItemsDictionary.Count == 0 || !IsLoaded)
194 {
195 return;
196 }
197 // 获取选中项
198 var item = ItemsDictionary[SelectedIndex];
199 var oldSelectedItem = ItemsDictionary[oldSelectedIndex];
200
201 // 选中项的坐标
202 Point relativePoint = item.TransformToAncestor(this).Transform(new Point(0, 0));
203
204 double scrollX = relativePoint.X;
205
206 scrollX = scrollX < 0 ? 0 : scrollX;
207 scrollAnimation.To = scrollX;
208
209
210
211
212
213 // 文字颜色动画
214 fontColorAnimation.To = SelectedTextColor;
215 Storyboard.SetTarget(fontColorAnimation, item);
216
217
218 if (oldSelectedIndex != SelectedIndex)
219 {
220 Storyboard.SetTarget(oldFontColorAnimation, oldSelectedItem);
221 storyboard.Children.Add(oldFontColorAnimation);
222 }
223 else
224 {
225 storyboard.Children.Remove(oldFontColorAnimation);
226 }
227 storyboard.Begin();
228 }
229
230 private void Reset()
231 {
232 Storyboard storyboard = new Storyboard();
233
234 foreach (var item in ItemsContainer.Children)
235 {
236 if (item != ItemsContainer.Children[SelectedIndex])
237 {
238 var text = item as TextBlock;
239 text.Foreground = UI.Base.Color.Colors.GetFromString("#ccc");
240
241 }
242 }
243
244 }
245 }
246}