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   豆浆咖啡  阅读(1504)  评论(0编辑  收藏  举报

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
< 2013年3月 >
24 25 26 27 28 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31 1 2 3 4 5 6

统计

点击右上角即可分享
微信分享提示