View difference between Paste ID: Qyqb2UZx and 7Xw0BsrN
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
}