SHOW:
|
|
- or go back to the newest paste.
1 | using System; | |
2 | using System.Collections.Generic; | |
3 | using System.Linq; | |
4 | using System.Text; | |
5 | using System.Threading.Tasks; | |
6 | using System.Windows; | |
7 | using System.Windows.Controls; | |
8 | using System.Windows.Documents; | |
9 | using System.Windows.Media; | |
10 | ||
11 | namespace SO3WPF | |
12 | { | |
13 | public class HighlightTextBlock : ContentControl | |
14 | { | |
15 | ||
16 | public string Text | |
17 | { | |
18 | get { return (string)GetValue(TextProperty); } | |
19 | set { SetValue(TextProperty, value); } | |
20 | } | |
21 | ||
22 | public static readonly DependencyProperty TextProperty = | |
23 | DependencyProperty.Register("Text", typeof(string), typeof(HighlightTextBlock), new UIPropertyMetadata("", SetContentStatic)); | |
24 | ||
25 | private static void SetContentStatic(DependencyObject d, DependencyPropertyChangedEventArgs e) | |
26 | { | |
27 | var control = d as HighlightTextBlock; | |
28 | control.SetContent(); | |
29 | } | |
30 | ||
31 | public string HighlightText | |
32 | { | |
33 | get { return (string)GetValue(HighlightTextProperty); } | |
34 | set { SetValue(HighlightTextProperty, value); } | |
35 | } | |
36 | ||
37 | public static readonly DependencyProperty HighlightTextProperty = | |
38 | DependencyProperty.Register("HighlightText", typeof(string), typeof(HighlightTextBlock), new UIPropertyMetadata("", SetContentStatic)); | |
39 | ||
40 | public Brush HighlightBrush | |
41 | { | |
42 | get { return (Brush)GetValue(ColorProperty); } | |
43 | set { SetValue(ColorProperty, value); } | |
44 | } | |
45 | ||
46 | public static readonly DependencyProperty ColorProperty = | |
47 | DependencyProperty.Register("HighlightBrush", typeof(Brush), typeof(HighlightTextBlock), new UIPropertyMetadata(Brushes.Orange)); | |
48 | ||
49 | private TextBlock TextContent = new TextBlock(); | |
50 | ||
51 | public HighlightTextBlock() | |
52 | { | |
53 | Content = TextContent; | |
54 | SetContent(); | |
55 | } | |
56 | ||
57 | int updateId = 0; | |
58 | private void SetContentOld() | |
59 | { | |
60 | var currentUpdateId = ++updateId; | |
61 | var text = Text; | |
62 | var highlightText = HighlightText; | |
63 | var parts = GetCombined(text, highlightText);//await Task.Run(() => GetCombined(text, highlightText)); | |
64 | if (currentUpdateId != updateId) | |
65 | return; | |
66 | ApplyParts(parts); | |
67 | } | |
68 | ||
69 | Task currentWaitTask = null; | |
70 | private async void SetContent45() | |
71 | { | |
72 | var waitTask = Task.Delay(TimeSpan.FromSeconds(0.1)); | |
73 | currentWaitTask = waitTask; | |
74 | await waitTask; | |
75 | if (currentWaitTask != waitTask) | |
76 | return; | |
77 | ||
78 | var text = Text; | |
79 | var highlightText = HighlightText; | |
80 | var parts = await Task.Run(() => GetCombined(text, highlightText)); | |
81 | if (currentWaitTask != waitTask) | |
82 | return; | |
83 | ||
84 | currentWaitTask = null; | |
85 | ApplyParts(parts); | |
86 | } | |
87 | ||
88 | private void SetContent() | |
89 | { | |
90 | var mainTS = TaskScheduler.FromCurrentSynchronizationContext(); | |
91 | var waitTask = Task.Delay(TimeSpan.FromSeconds(0.1)); | |
92 | currentWaitTask = waitTask; | |
93 | waitTask.ContinueWith(t => | |
94 | { | |
95 | if (currentWaitTask != waitTask) | |
96 | return; | |
97 | var text = Text; | |
98 | var highlightText = HighlightText; | |
99 | ||
100 | - | Task.Run(() => GetCombined(text, highlightText)).ContinueWith(ctask => |
100 | + | var parts = GetCombined(text, highlightText); |
101 | - | { |
101 | + | currentWaitTask = null; |
102 | - | var parts = ctask.Result; |
102 | + | ApplyParts(parts); |
103 | - | if (currentWaitTask != waitTask) |
103 | + | |
104 | - | return; |
104 | + | |
105 | - | currentWaitTask = null; |
105 | + | |
106 | - | ApplyParts(parts); |
106 | + | |
107 | - | }, mainTS); |
107 | + | |
108 | var highlightBrush = HighlightBrush; | |
109 | System.Collections.IList existingInlines = TextContent.Inlines; | |
110 | var existingCount = existingInlines.Count; | |
111 | List<Inline> inlinesToAdd = null; | |
112 | var max = Math.Max(existingCount, parts.Count); | |
113 | for (int i = 0; i < max; i++) | |
114 | { | |
115 | var text = i < parts.Count ? parts[i] : null; | |
116 | if (i < existingCount) | |
117 | { | |
118 | ((Run)existingInlines[i]).Text = text; | |
119 | } | |
120 | else // add new inline | |
121 | { | |
122 | var inline = new Run(text); | |
123 | if (i % 2 != 0) // highlight | |
124 | inline.Background = highlightBrush; | |
125 | if (inlinesToAdd == null) | |
126 | inlinesToAdd = new List<Inline>(parts.Count); | |
127 | inlinesToAdd.Add(inline); | |
128 | } | |
129 | } | |
130 | if (inlinesToAdd != null) | |
131 | TextContent.Inlines.AddRange(inlinesToAdd); | |
132 | } | |
133 | ||
134 | private List<string> GetCombined(string text, string highlightText) | |
135 | { | |
136 | var list = new List<string>(); | |
137 | if (text == null) | |
138 | return list; | |
139 | if (highlightText == null) | |
140 | { | |
141 | list.Add(text); | |
142 | return list; | |
143 | } | |
144 | ||
145 | var parts = text.Split(new[] { highlightText }, StringSplitOptions.None); | |
146 | bool first = true; | |
147 | foreach (var part in parts) | |
148 | { | |
149 | if (!first) | |
150 | list.Add(highlightText); | |
151 | list.Add(part); | |
152 | first = false; | |
153 | } | |
154 | return list; | |
155 | } | |
156 | } | |
157 | } |