windows8开发笔记(6)-ListView筛选汉字以及高亮关键字

    在Windows8商店应用开发中,要让ListView中让指定的关键字高亮,就如下图所示的那样..输入一个z,ListView自动把首字母是z的字全部高亮了,下面我来说说这到底是怎么做到的。

     我们来分析一下这个过程,首先要把z为首字母的汉字找出来,然后让这些汉字在ListView中高亮,并且要让ListView行中不同的关键字高亮。过程大概是这样的。

     1、找出所有的汉字首字母

        public static string GetPinyinCode(string unicodeString)
        {
            int i = 0;
            ushort key = 0;
            string strResult = string.Empty;         
            Encoding unicode = Encoding.Unicode;
            Encoding gbk = Encoding.GetEncoding("GBK");
            byte[] unicodeBytes = unicode.GetBytes(unicodeString);
            byte[] gbkBytes = Encoding.Convert(unicode, gbk, unicodeBytes);
            while (i < gbkBytes.Length)
            {
        
                if (gbkBytes[i] <= 127)
                {
                    strResult = strResult + (char)gbkBytes[i];
                    i++;
                }
                #region
                else
                {
                    key = (ushort)(gbkBytes[i] * 256 + gbkBytes[i + 1]);
                    if (key >= '\uB0A1' && key <= '\uB0C4')
                    {
                        strResult = strResult + "A";
                    }
                    else if (key >= '\uB0C5' && key <= '\uB2C0')
                    {
                        strResult = strResult + "B";
                    }
                    else if (key >= '\uB2C1' && key <= '\uB4ED')
                    {
                        strResult = strResult + "C";
                    }
                    else if (key >= '\uB4EE' && key <= '\uB6E9')
                    {
                        strResult = strResult + "D";
                    }
                    else if (key >= '\uB6EA' && key <= '\uB7A1')
                    {
                        strResult = strResult + "E";
                    }
                    else if (key >= '\uB7A2' && key <= '\uB8C0')
                    {
                        strResult = strResult + "F";
                    }
                    else if (key >= '\uB8C1' && key <= '\uB9FD')
                    {
                        strResult = strResult + "G";
                    }
                    else if (key >= '\uB9FE' && key <= '\uBBF6')
                    {
                        strResult = strResult + "H";
                    }
                    else if (key >= '\uBBF7' && key <= '\uBFA5')
                    {
                        strResult = strResult + "J";
                    }
                    else if (key >= '\uBFA6' && key <= '\uC0AB')
                    {
                        strResult = strResult + "K";
                    }
                    else if (key >= '\uC0AC' && key <= '\uC2E7')
                    {
                        strResult = strResult + "L";
                    }
                    else if (key >= '\uC2E8' && key <= '\uC4C2')
                    {
                        strResult = strResult + "M";
                    }
                    else if (key >= '\uC4C3' && key <= '\uC5B5')
                    {
                        strResult = strResult + "N";
                    }
                    else if (key >= '\uC5B6' && key <= '\uC5BD')
                    {
                        strResult = strResult + "O";
                    }
                    else if (key >= '\uC5BE' && key <= '\uC6D9')
                    {
                        strResult = strResult + "P";
                    }
                    else if (key >= '\uC6DA' && key <= '\uC8BA')
                    {
                        strResult = strResult + "Q";
                    }
                    else if (key >= '\uC8BB' && key <= '\uC8F5')
                    {
                        strResult = strResult + "R";
                    }
                    else if (key >= '\uC8F6' && key <= '\uCBF9')
                    {
                        strResult = strResult + "S";
                    }
                    else if (key >= '\uCBFA' && key <= '\uCDD9')
                    {
                        strResult = strResult + "T";
                    }
                    else if (key >= '\uCDDA' && key <= '\uCEF3')
                    {
                        strResult = strResult + "W";
                    }
                    else if (key >= '\uCEF4' && key <= '\uD188')
                    {
                        strResult = strResult + "X";
                    }
                    else if (key >= '\uD1B9' && key <= '\uD4D0')
                    {
                        strResult = strResult + "Y";
                    }
                    else if (key >= '\uD4D1' && key <= '\uD7F9')
                    {
                        strResult = strResult + "Z";
                    }
                    else
                    {
                        strResult = strResult + "?";
                    }
                    i = i + 2;
                }
                #endregion
            }
            return strResult;
        }

    2、筛选出高亮关键字,代码大致如下

      List<DeliveryItem> list = new List<DeliveryItem>();

            foreach (var item in App.CompanyCollection)
            {
                var pinyin = Helper.GetPinyinCode(item.DisplayName).ToLower();
                int index = pinyin.IndexOf(query);
                if (index >= 0)//item.Alias.Contains(tb.Text)
                {
                    DeliveryItem temp = item;
                    temp.LightName = temp.DisplayName.Substring(index, query.Length);
                    list.Add(temp);
                }
                else if (item.DisplayName.Contains(tb.Text))
                {
                    DeliveryItem temp = item;
                    temp.LightName = query;
                    list.Add(temp);
                }

            }

     3、构建ListView我们这里需要用到一个控件HighlightingTextBlock,这是Silverlight时代的一个控件,我把它翻译成了适合Windows8商店应用的控件

using System;
using System.Collections.Generic;
using System.Windows;
using Windows.UI;
using Windows.UI.Text;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Documents;
using Windows.UI.Xaml.Media;

namespace Express.Controls
{
    public partial class HighlightingTextBlock : Control
    {
        /// <summary>   
        /// The name of the TextBlock part.   
        /// </summary>   
        private string TextBlockName = "Text";

        /// <summary>   
        /// Gets or sets the text block reference.   
        /// </summary>   
        private TextBlock TextBlock { get; set; }

        /// <summary>   
        /// Gets or sets the inlines list.   
        /// </summary>   
        private List<Inline> Inlines { get; set; }

        #region public string Text
        /// <summary>   
        /// Gets or sets the contents of the TextBox.   
        /// </summary>   
        public string Text
        {
            get { return GetValue(TextProperty) as string; }
            set { SetValue(TextProperty, value); }
        }

        /// <summary>   
        /// Identifies the Text dependency property.   
        /// </summary>   
        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register(
                "Text",
                typeof(string),
                typeof(HighlightingTextBlock),
                new PropertyMetadata("", OnTextPropertyChanged));

        /// <summary>   
        /// TextProperty property changed handler.   
        /// </summary>   
        /// <param name="d">AutoCompleteBox that changed its Text.</param>   
        /// <param name="e">Event arguments.</param>   
        private static void OnTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            HighlightingTextBlock source = d as HighlightingTextBlock;

            if (source.TextBlock != null)
            {
                while (source.TextBlock.Inlines.Count > 0)
                {
                    source.TextBlock.Inlines.RemoveAt(0);
                }
                string value = e.NewValue as string;
                source.Inlines = new List<Inline>();
                if (value != null)
                {
                    for (int i = 0; i < value.Length; i++)
                    {
                        Inline run = new Run { Text = value[i].ToString() };
                        source.TextBlock.Inlines.Add(run);
                        source.Inlines.Add(run);
                    }

                    source.ApplyHighlighting();
                }
            }
        }

        #endregion public string Text

        #region public string HighlightText
        /// <summary>   
        /// Gets or sets the highlighted text.   
        /// </summary>   
        public string HighlightText
        {
            get { return GetValue(HighlightTextProperty) as string; }
            set { SetValue(HighlightTextProperty, value); }
        }

        /// <summary>   
        /// Identifies the HighlightText dependency property.   
        /// </summary>   
        public static readonly DependencyProperty HighlightTextProperty =
            DependencyProperty.Register(
                "HighlightText",
                typeof(string),
                typeof(HighlightingTextBlock),
                new PropertyMetadata("", OnHighlightTextPropertyChanged));

        /// <summary>   
        /// HighlightText property changed handler.   
        /// </summary>   
        /// <param name="d">AutoCompleteBox that changed its HighlightText.</param>   
        /// <param name="e">Event arguments.</param>   
        private static void OnHighlightTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            HighlightingTextBlock source = d as HighlightingTextBlock;
            source.ApplyHighlighting();
        }

        #endregion public string HighlightText

        #region public Brush HighlightBrush
        /// <summary>   
        /// Gets or sets the highlight brush.   
        /// </summary>   
        public Brush HighlightBrush
        {
            get { return GetValue(HighlightBrushProperty) as Brush; }
            set { SetValue(HighlightBrushProperty, value); }
        }

        /// <summary>   
        /// Identifies the HighlightBrush dependency property.   
        /// </summary>   
        public static readonly DependencyProperty HighlightBrushProperty =
            DependencyProperty.Register(
                "HighlightBrush",
                typeof(Brush),
                typeof(HighlightingTextBlock),
                new PropertyMetadata(new SolidColorBrush(Colors.BlueViolet), OnHighlightBrushPropertyChanged));

        /// <summary>   
        /// HighlightBrushProperty property changed handler.   
        /// </summary>   
        /// <param name="d">HighlightingTextBlock that changed its HighlightBrush.</param>   
        /// <param name="e">Event arguments.</param>   
        private static void OnHighlightBrushPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            HighlightingTextBlock source = d as HighlightingTextBlock;
            source.ApplyHighlighting();
        }
        #endregion public Brush HighlightBrush

        #region public FontWeight HighlightFontWeight
        /// <summary>   
        /// Gets or sets the font weight used on highlighted text.   
        /// </summary>   
        public FontWeight HighlightFontWeight
        {
            get { return (FontWeight)GetValue(HighlightFontWeightProperty); }
            set { SetValue(HighlightFontWeightProperty, value); }
        }

        /// <summary>   
        /// Identifies the HighlightFontWeight dependency property.   
        /// </summary>   
        public static readonly DependencyProperty HighlightFontWeightProperty =
            DependencyProperty.Register(
                "HighlightFontWeight",
                typeof(FontWeight),
                typeof(HighlightingTextBlock),
                new PropertyMetadata(FontWeights.Normal, OnHighlightFontWeightPropertyChanged));

        /// <summary>   
        /// HighlightFontWeightProperty property changed handler.   
        /// </summary>   
        /// <param name="d">HighlightingTextBlock that changed its HighlightFontWeight.</param>   
        /// <param name="e">Event arguments.</param>   
        private static void OnHighlightFontWeightPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            HighlightingTextBlock source = d as HighlightingTextBlock;
            FontWeight value = (FontWeight)e.NewValue;
        }
        #endregion public FontWeight HighlightFontWeight

        /// <summary>   
        /// Initializes a new HighlightingTextBlock class.   
        /// </summary>   
        public HighlightingTextBlock()
        {
            DefaultStyleKey = typeof(HighlightingTextBlock);
            Loaded += OnLoaded;
        }

        /// <summary>   
        /// Loaded method handler.   
        /// </summary>   
        /// <param name="sender">The loaded event.</param>   
        /// <param name="e">The event data.</param>   
        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            OnApplyTemplate();
        }

        /// <summary>   
        /// Override the apply template handler.   
        /// </summary>   
        protected override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            // Grab the template part   
            TextBlock = GetTemplateChild(TextBlockName) as TextBlock;

            // Re-apply the text value   
            string text = Text;
            Text = null;
            Text = text;
        }

        /// <summary>   
        /// Apply the visual highlighting.   
        /// </summary>   
        private void ApplyHighlighting()
        {
            if (Inlines == null)
            {
                return;
            }

            string text = Text ?? string.Empty;
            string highlight = HighlightText ?? string.Empty;
            StringComparison compare = StringComparison.OrdinalIgnoreCase;

            int cur = 0;
            while (cur < text.Length)
            {
                int i = highlight.Length == 0 ? -1 : text.IndexOf(highlight, cur, compare);
                i = i < 0 ? text.Length : i;

                // Clear   
                while (cur < i && cur < text.Length)
                {
                    Inlines[cur].Foreground = Foreground;
                    Inlines[cur].FontWeight = FontWeight;
                    cur++;
                }

                // Highlight   
                int start = cur;
                while (cur < start + highlight.Length && cur < text.Length)
                {
                    Inlines[cur].Foreground = HighlightBrush;
                    Inlines[cur].FontWeight = HighlightFontWeight;
                    cur++;
                }
            }
        }
    }
}


    这是一个模版化控件,我们还需要在Generic.xaml里面添加下面代码

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:contorls="using:Express.Controls"
    xmlns:local="using:Express">


    <Style TargetType="contorls:HighlightingTextBlock">
        <Setter Property="HighlightBrush" Value="Blue" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="contorls:HighlightingTextBlock">
                    <TextBlock x:Name="Text" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

 

   下面就很简单了,构建一个ListView,代码大致如下

  <ListView Margin="10,70,0,0"  BorderBrush="Black"  ItemContainerStyle="{StaticResource ListDetailItem}"
                          HorizontalAlignment="Left" 
                          ItemsSource="{Binding FilterList, Mode=TwoWay}" >
                    <Interactivity:Interaction.Triggers>
                        <Interactivity:EventTrigger EventName="Loaded">
                            <Actions:CallMethodAction TargetObject="{Binding Main, Source={StaticResource Locator}}"
                                   MethodName="GridView_Loaded" />
                        </Interactivity:EventTrigger>
                        <Interactivity:EventTrigger EventName="SelectionChanged">
                            <Actions:CallMethodAction TargetObject="{Binding Main, Source={StaticResource Locator}}"
                                   MethodName="FilteredSelectionChanged" />
                        </Interactivity:EventTrigger>
                    </Interactivity:Interaction.Triggers>
                    <ListView.ItemTemplate>
                        <DataTemplate>
                      
                            <contorls:HighlightingTextBlock VerticalAlignment="Center" Margin="9,0,0,0" HighlightText="{Binding LightName}"
                                                            Text="{Binding DisplayName}" HighlightBrush="#3db0da"/>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>

       这时候筛选出的ListView只要绑定筛选出的列表就会高亮相关的关键字了。

        代码大致如上所示,因为是我程序摘抄出来的,有些部分大家需要手动修改一下,我主要说的是思路,希望大家动手后会更深刻,欢迎留言讨论。

      

 

posted on 2013-03-09 20:42  豆浆咖啡  阅读(1487)  评论(0编辑  收藏  举报