跳到主要内容

github/tai

公开

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

浏览文件

BaseList.cs

185 行 · 5.8 KB历史下载
1using System;
2using System.Collections.Generic;
3using System.Collections.ObjectModel;
4using System.Diagnostics;
5using System.Linq;
6using System.Text;
7using System.Threading.Tasks;
8using System.Windows;
9using System.Windows.Controls;
10using System.Windows.Input;
11
12namespace UI.Controls.List
13{
14 public class BaseList : Control
15 {
16 public ObservableCollection<string> Items { get { return (ObservableCollection<string>)GetValue(ItemsProperty); } set { SetValue(ItemsProperty, value); } }
17 public static readonly DependencyProperty ItemsProperty = DependencyProperty.Register("Items", typeof(ObservableCollection<string>), typeof(BaseList), new PropertyMetadata(new PropertyChangedCallback(ItemsChanged)));
18
19 private static void ItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
20 {
21 var control = d as BaseList;
22 if (e.NewValue != e.OldValue)
23 {
24 control.Render();
25 control.AddCollectionChangedHandler();
26 }
27 }
28
29 public string SelectedItem { get { return (string)GetValue(SelectedItemProperty); } set { SetValue(SelectedItemProperty, value); } }
30 public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem", typeof(string), typeof(BaseList), new PropertyMetadata(new PropertyChangedCallback(OnSelectedItemChanged)));
31
32 private static void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
33 {
34 var that = (BaseList)d;
35 if (e.NewValue != e.OldValue)
36 {
37 that.OnSelect();
38 }
39 }
40
41 private StackPanel Container;
42
43 //private Dictionary<int, BaseListItem> ItemsMap;
44 private List<BaseListItem> ItemsMap;
45 private ScrollViewer ScrollViewer;
46
47 /// <summary>
48 /// 选择项更改后发生
49 /// </summary>
50 public event EventHandler SelectedItemChanged;
51 public BaseList()
52 {
53 DefaultStyleKey = typeof(BaseList);
54 Items = new ObservableCollection<string>();
55 ItemsMap = new List<BaseListItem>();
56 AddCollectionChangedHandler();
57 }
58
59 private void AddCollectionChangedHandler()
60 {
61 if (Items == null) return;
62
63 Items.CollectionChanged -= Items_CollectionChanged;
64 Items.CollectionChanged += Items_CollectionChanged;
65 }
66
67 private void Items_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
68 {
69 if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
70 {
71 foreach (var item in e.NewItems)
72 {
73 AddItem(item as string);
74 }
75 }
76
77 if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
78 {
79 foreach (var item in e.OldItems)
80 {
81 RemoveItem(item as string);
82 }
83 }
84 }
85
86 public override void OnApplyTemplate()
87 {
88 base.OnApplyTemplate();
89 Container = GetTemplateChild("Container") as StackPanel;
90 ScrollViewer = GetTemplateChild("ScrollViewer") as ScrollViewer;
91
92 Render();
93 }
94
95 private void Render()
96 {
97 if (Container != null)
98 {
99 Container.Children.Clear();
100 ItemsMap.Clear();
101
102 if (Items == null)
103 {
104 return;
105 }
106
107 foreach (var item in Items)
108 {
109 AddItem(item);
110 }
111 }
112 }
113
114 private void AddItem(string item)
115 {
116 if (Container == null)
117 {
118 return;
119 }
120 var itemControl = new BaseListItem();
121 itemControl.Text = item;
122 itemControl.MouseLeftButtonUp += ItemClick;
123 itemControl.MouseRightButtonUp += ItemClick;
124 bool isHandleSelected = false;
125 if (SelectedItem == item)
126 {
127 itemControl.IsSelected = true;
128
129 itemControl.Loaded += (e, c) =>
130 {
131 if (isHandleSelected)
132 {
133 return;
134 }
135 isHandleSelected = true;
136 ScrollViewer.ScrollToVerticalOffset(itemControl.TransformToAncestor(Container)
137 .Transform(new Point(0, 0)).Y);
138 };
139 }
140
141 ItemsMap.Add(itemControl);
142 Container.Children.Add(itemControl);
143 }
144
145 private void RemoveItem(string item)
146 {
147 if (Container == null)
148 {
149 return;
150 }
151 var control = ItemsMap.Where(m => m.Text == item).FirstOrDefault();
152 if (control != null)
153 {
154 Container.Children.Remove(control);
155 }
156 }
157
158 private void ItemClick(object sender, MouseButtonEventArgs e)
159 {
160 ClearSelectedItems();
161 (sender as BaseListItem).IsSelected = true;
162 SelectedItem = (sender as BaseListItem).Text;
163 SelectedItemChanged?.Invoke(this, EventArgs.Empty);
164 }
165
166 private void ClearSelectedItems()
167 {
168 foreach (var item in ItemsMap)
169 {
170 item.IsSelected = false;
171 }
172 }
173
174
175 private void OnSelect()
176 {
177 ClearSelectedItems();
178 var control = ItemsMap.Where(m => m.Text == SelectedItem).FirstOrDefault();
179 if (control != null)
180 {
181 control.IsSelected = true;
182 }
183 }
184 }
185}