如何给wp(Windows phone)中搜索关键字加亮?

问题来源

最近在群里看到群友讨论在wp中有个搜索功能,要求搜索关键字在搜索结果内容中加亮(即加颜色),由于wp中没有自带这样的控件,于是大家各抒自见,有人说用第三方控件,有人说用richtextbox,也有人说用textblock和run!那究竟哪种实现比较好呢?个人看法,当然是用textblock和run实现起来是最方便的!

实现要求

1、给出关键字(如:我,购物,菜鸟,技术),关键字可以一个或者多个,多个用英文逗号隔开

2、能在搜索结果中对关键字进行加亮

3、能自定义加亮的颜色

4、要求复用性高

实现思路

如果要实现上面三点需求,首先我们想到是使用用户控件实现起来最好了,第一,二,三点分别用一个依赖属性表示,而第四点,既然是用户控件,作为一个控件,当然复用性强!

所以使用用户控件是再适合不过了!

材料准备

首先当然是在vs中新建一个wp的项目,然后添加一个用户控件的页面,这个估计不用我多说了,大家都会的了!在这里我新增一个HighlightControl的用户控件页面,在界面上添加一个TextBlock,命名为tbResult,打开codebehind,分别添加三个依赖属性,分别是TextProperty(搜索结果),HighlightWordProperty(关键字),HighlightWordColorProperty(加亮颜色),然后添加对应的包装属性,再添加回调方法!这些应该不用详解吧,学过wpf或者silverlight对这些应该很了解了!如果不懂可以评论问问!

 

下面贴出用户控件codebehind相应代码

 

  1  public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(HighlightControl), new PropertyMetadata(new PropertyChangedCallback(HighlightControl.OnTextChanged)));

  2         public static readonly DependencyProperty HighlightWordProperty = DependencyProperty.Register("HighlightWord", typeof(string), typeof(HighlightControl), new PropertyMetadata(new PropertyChangedCallback(HighlightControl.OnHighlightWordChanged)));

  3         public static readonly DependencyProperty HighlightWordColorProperty = DependencyProperty.Register("HighlightWordColor", typeof(SolidColorBrush), typeof(HighlightControl), new PropertyMetadata(new SolidColorBrush(Color.FromArgb(255, 0, 155, 227)), new PropertyChangedCallback(HighlightControl.OnHighlightWordColorChanged)));

  4 

  5         public string Text

  6         {

  7             get

  8             {

  9                 return (string)base.GetValue(HighlightControl.TextProperty);

 10             }

 11             set

 12             {

 13                 base.SetValue(HighlightControl.TextProperty, value);

 14             }

 15         }

 16 

 17         public SolidColorBrush HighlightWordColor

 18         {

 19             get

 20             {

 21                 return (SolidColorBrush)base.GetValue(HighlightControl.HighlightWordColorProperty);

 22             }

 23             set

 24             {

 25                 base.SetValue(HighlightControl.HighlightWordColorProperty, value);

 26             }

 27         }

 28 

 29         public string HighlightWord

 30         {

 31             get

 32             {

 33                 return (string)base.GetValue(HighlightControl.HighlightWordProperty);

 34             }

 35             set

 36             {

 37                 base.SetValue(HighlightControl.HighlightWordProperty, value);

 38             }

 39         }

 40 

 41 

 42         private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

 43         {

 44             HighlightControl control = d as HighlightControl;

 45             if (e.NewValue == e.OldValue)

 46             {

 47                 return;

 48             }

 49             HighlightControl.UpdateHighlight(control);

 50         }

 51 

 52         private static void OnHighlightWordChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

 53         {

 54             HighlightControl control = d as HighlightControl;

 55             HighlightControl.UpdateHighlight(control);

 56         }

 57 

 58         private static void OnHighlightWordColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

 59         {

 60             HighlightControl control = d as HighlightControl;

 61             HighlightControl.UpdateHighlight(control);

 62         }

 63 

 64 

 65 

 66 

 67 

 68         private static void UpdateHighlight(HighlightControl control)

 69         {

 70             if (control == null)

 71             {

 72                 return;

 73             }

 74             TextBlock textBlock = control.tbResult;

 75             if (textBlock.Inlines.Count() > 0)

 76             {

 77                 textBlock.Inlines.Clear();

 78             }

 79             //如果高亮为空,直接显示

 80             if (string.IsNullOrEmpty(control.HighlightWord))

 81             {

 82                 Run run = new Run();

 83                 run.Text = control.Text;

 84                 textBlock.Inlines.Add(run);

 85                 return;

 86             }

 87             string text = control.Text;

 88             if (string.IsNullOrEmpty(text))

 89             {

 90                 return;

 91             }

 92             TextBlock tempTextBlock = new TextBlock();//中间变量,方便run交换

 93             string[] hightwordArray = control.HighlightWord.Split(',');

 94             List<Run> listHightRun = new List<Run>();//添加已经加亮的run,方便判断

 95             for (int i = 0; i < hightwordArray.Length; i++)

 96             {

 97                 if (hightwordArray[i] == "") continue;//这个是放在关键字中有"",导致死循环

 98 

 99                 if (i == 0)

100                 {

101                     for (int num = text.IndexOf(hightwordArray[i], 0); num != -1; num = text.IndexOf(hightwordArray[i], 0))

102                     {

103                         //  MessageBox.Show(num.ToString());

104                         if (num != 0)

105                         {

106                             Run run2 = new Run();

107                             run2.Text = text.Substring(0, num);

108                             // textBlock.Inlines.Add(run2);

109                             tempTextBlock.Inlines.Add(run2);

110 

111                         }

112                         Run run3 = new Run();

113                         run3.Text = text.Substring(num, hightwordArray[i].Length);

114                         run3.Foreground = control.HighlightWordColor;

115                         listHightRun.Add(run3);

116                         //textBlock.Inlines.Add(run3);

117                         tempTextBlock.Inlines.Add(run3);

118                         text = text.Substring(num + hightwordArray[i].Length);

119                         // MessageBox.Show(text);

120                     }

121                     if (!string.IsNullOrEmpty(text))

122                     {

123                         Run run4 = new Run();

124                         run4.Text = text;

125                         tempTextBlock.Inlines.Add(run4);//剩下没有被加亮的文字,加到一个run

126                     }

127 

128                 }

129                 else

130                 {

131                     // text = control.Text;

132                     //  MessageBox.Show("要遍历textBlock长度:" + textBlock.Inlines.Count.ToString());

133                     for (int j = 0; j < textBlock.Inlines.Count; j++)

134                     {

135                         if (listHightRun.Any(h => h.Equals((textBlock.Inlines[j] as Run))))//如果是一个加亮的run,那就不需要遍历了

136                         {

137                             // MessageBox.Show("jin" + (textBlock.Inlines[j] as Run).Text);

138                             Run runExist = (textBlock.Inlines[j] as Run);

139                             textBlock.Inlines.Remove(textBlock.Inlines[j]);

140                             tempTextBlock.Inlines.Add(runExist);

141                             j--;

142                             //  MessageBox.Show("移除元素后textBlock长度:" + textBlock.Inlines.Count + "  j: " + j);

143                             continue;

144                         }

145                         string tempStr = (textBlock.Inlines[j] as Run).Text;

146                         for (int num = tempStr.IndexOf(hightwordArray[i], 0); num != -1; num = tempStr.IndexOf(hightwordArray[i], 0))

147                         {

148                             //MessageBox.Show("要遍历的字符串:"+tempStr);

149                             //MessageBox.Show("关键字是否存在:"+num.ToString());

150                             //MessageBox.Show("关键字:"+hightwordArray[i]);

151                             if (num != 0)

152                             {

153                                 Run run2 = new Run();

154                                 run2.Text = tempStr.Substring(0, num);

155 

156                                 tempTextBlock.Inlines.Add(run2);

157                             }

158                             Run run3 = new Run();

159                             run3.Text = tempStr.Substring(num, hightwordArray[i].Length);

160                             run3.Foreground = control.HighlightWordColor;

161                             listHightRun.Add(run3);

162                             tempTextBlock.Inlines.Add(run3);

163                             tempStr = tempStr.Substring(num + hightwordArray[i].Length);

164                             // (textBlock.Inlines[j] as Run).Text = (textBlock.Inlines[j] as Run).Text.Substring(num + hightwordArray[i].Length);

165                         }

166                         if (!string.IsNullOrEmpty(tempStr))//剩下没有被加亮的文字,加到一个run

167                         {

168                             Run run4 = new Run();

169                             run4.Text = tempStr;

170                             tempTextBlock.Inlines.Add(run4);

171                         }

172                     }

173                 }

174                 textBlock.Inlines.Clear();

175 

176                 int k = 0;

177                 while (k < tempTextBlock.Inlines.Count)

178                 {

179                     Run tempRun = tempTextBlock.Inlines[k] as Run;

180                     tempTextBlock.Inlines.Remove(tempTextBlock.Inlines[k]);

181                     textBlock.Inlines.Add(tempRun);

182                     k = 0;

183 

184                 }

185 

186                 //tempTextBlock.Inlines.Clear();

187 

188             }

189 

190 

191 

192         }

 

测试页面代码

 

 1    <!--LayoutRoot 是包含所有页面内容的根网格-->

 2     <Grid x:Name="LayoutRoot" Background="Transparent">

 3         <Grid.RowDefinitions>

 4             <RowDefinition Height="Auto"/>

 5             <RowDefinition Height="*"/>

 6         </Grid.RowDefinitions>

 7 

 8     

 9 

10         <!--TitlePanel 包含应用程序的名称和页标题-->

11         <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">

12             <TextBlock Text="我的应用程序" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>

13             <TextBlock Text="页面名称" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>

14         </StackPanel>

15 

16         <!--ContentPanel - 在此处放置其他内容-->

17         <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">

18             

19             <control:HighlightControl Text="这是一个显示加亮在搜索结果中的关键字的用户控件" HighlightWord="高,的,这是,测试,亮,段" HighlightWordColor="Red">

20                 

21             </control:HighlightControl>

22 

23         </Grid>

24 

25        

26     </Grid>

 


整个实现大概就是这样,最后截一张图给大家看看。

 

 如何给wp(Windows phone)中搜索关键字加亮?

总结

问题总有解决的方法的,很多你看似是比较困难的事情,其实都是由最基础的知识去一步步分解出来解决的,所以善于思考,举一反三,才是快速解决问题的根本途径!

你可能感兴趣的:(windows phone)