NEWS

[DEVEXPRESS] Tìm kiếm không dấu tô màu highlight có dấu trên C# Winform

[DEVEXPRESS] Tìm kiếm không dấu tô màu highlight có dấu trên C# Winform
Đăng bởi: Thảo Meo - Lượt xem: 3623 13:57:20, 15/06/2023C#   In bài viết

Xin chào các bạn, bài viết hôm nay mình chia sẻ các bạn cách tìm kiếm Tiếng Việt không dấu highlight có dấu trên Devexpress Winform C#.

[DEVEXPRESS] Search and Custom Highlight Text in Winform C#

Hình ảnh tìm kiếm không dấu có thể highlight có dấu Tiếng Việt:

search_highlight_c

Ở hình ảnh trên, các bạn thấy mình gõ vào từ khóa: cam thuy quang

=> kết quả nó tự hiểu và tìm kiếm Cam Thủy, Quảng Bình...

Video demo ứng dụng:

Source code C#:

using DevExpress.XtraEditors.Controls;
using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Diagnostics;
using System.Globalization;
using DevExpress.Utils.Paint;
using DevExpress.XtraGrid.Views.Base;
using DevExpress.Utils.Html.Internal;
using DevExpress.XtraPrinting.Native;
using DevExpress.XtraPrinting;
using DevExpress.XtraEditors;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;

namespace SearchHighLightNoneVietnamese
{
    public partial class Form1 : DevExpress.XtraEditors.XtraForm
    {
        private List<DVHC> listDVHC = new List<DVHC>();
        public Color foreColorHighLight = Color.White;
        public Color backgroundColorHighLight = Color.YellowGreen;
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            colorBackground.Color = backgroundColorHighLight;
            colorForeground.Color = foreColorHighLight;
        }
        protected override void OnShown(EventArgs e)
        {
            base.OnShown(e);
            var jsonRawData = File.ReadAllText("data.json");
            listDVHC = JsonConvert.DeserializeObject<List<DVHC>>(jsonRawData);
            cb_diadiem.Properties.DataSource = listDVHC;
            cb_diadiem.AutoSuggest += repositoryItemGridLookUpEdit1_AutoSuggest;
            gridLookUpEdit1View.CustomDrawCell += cbDiadiem_CustomDrawCell;
            cb_diadiem.Properties.ValueMember = "maxa";
            cb_diadiem.Properties.DisplayMember = "diadiem";
            cb_diadiem.Properties.PopupFormSize = new System.Drawing.Size(cb_diadiem.Width, 300);
            cb_diadiem.BeforePopup += Cb_diadiem_BeforePopup;
            cb_diadiem.Popup += Cb_diadiem_Popup;
            LoadTinhThanh();
            LoadQuanHuyen();
            LoadPhuongXa();
            this.KeyPreview = true;
            this.KeyDown += Form1_KeyDown;
        }

        private void Cb_diadiem_Popup(object sender, EventArgs e)
        {
            gridLookUpEdit1View.CustomDrawCell += cbDiadiem_CustomDrawCell;
        }

        private void Cb_diadiem_BeforePopup(object sender, EventArgs e)
        {
            gridLookUpEdit1View.CustomDrawCell -= cbDiadiem_CustomDrawCell;
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Control && e.KeyCode == Keys.K)
            {
                cb_diadiem.Focus();
                cb_diadiem.SelectAll();
            }
        }

        public void LoadTinhThanh() {
            var dataTinhThanh = listDVHC.Select(x => new { matinh = x.matinh, tentinh = x.tentinh }).Distinct().ToList();
            cb_tinhthanh.Properties.DataSource = dataTinhThanh;
            cb_tinhthanh.Properties.ValueMember = "matinh";
            cb_tinhthanh.Properties.DisplayMember = "tentinh";
        }

        public void LoadQuanHuyen()
        {
            var dataQuanHuyen = listDVHC.Select(x => new { mahuyen = x.mahuyen, tenhuyen = x.tenhuyen }).Distinct().ToList();
            cb_quanhuyen.Properties.DataSource = dataQuanHuyen;
            cb_quanhuyen.Properties.ValueMember = "mahuyen";
            cb_quanhuyen.Properties.DisplayMember = "tenhuyen";
        }

        public void LoadPhuongXa()
        {
            var dataPhuongXa = listDVHC.Select(x => new { maxa = x.maxa, tenxa = x.tenxa }).Distinct().ToList();
            cb_phuongxa.Properties.DataSource = dataPhuongXa;
            cb_phuongxa.Properties.ValueMember = "maxa";
            cb_phuongxa.Properties.DisplayMember = "tenxa";
        }

        private void cbDiadiem_CustomDrawCell(object sender, RowCellCustomDrawEventArgs e)
        {

            XPaint paint = new XPaint();
            MultiColorDrawStringParams drawParams = new MultiColorDrawStringParams(e.Appearance);


            var searchText = cb_diadiem.Text;



            if (e.DisplayText.Length < searchText.Length)
                return;

            
            drawParams.Bounds = e.Bounds;
            drawParams.Text = e.DisplayText;           
            string tmpStr = e.DisplayText;
           
            var searchIndexesListOrigin = getListIndexMatch(e.DisplayText, searchText);
            if (searchIndexesListOrigin.Count == 0) return;
          

            var searchIndexesList = searchIndexesListOrigin.OrderBy(x => x.Item2).ToList();
            if (searchIndexesList.Count() > 0)
            {
                drawParams.Ranges = new CharacterRangeWithFormat[searchIndexesList.Count() * 2 + 1];
                int currentStrIndex = 0;
                int i = 0;
                while (i < searchIndexesList.Count())
                {
                    drawParams.Ranges[i * 2] = new CharacterRangeWithFormat(currentStrIndex, searchIndexesList[i].Item2 - currentStrIndex, e.Appearance.ForeColor, e.Appearance.BackColor);
                    drawParams.Ranges[i * 2 + 1] = new CharacterRangeWithFormat(searchIndexesList[i].Item2, searchIndexesList[i].Item3 - searchIndexesList[i].Item2, foreColorHighLight, backgroundColorHighLight);
                    currentStrIndex = searchIndexesList[i].Item3;
                    i++;
                }
                drawParams.Ranges[i * 2] = new CharacterRangeWithFormat(currentStrIndex, e.DisplayText.Length - currentStrIndex, e.Appearance.ForeColor, e.Appearance.BackColor);
                drawParams.Ranges = drawParams.Ranges.Where(val => val.Length != 0).ToArray();
            }
            paint.MultiColorDrawString(new DevExpress.Utils.Drawing.GraphicsCache(e.Graphics), drawParams);
            e.Handled = true;
            
        }

        public  int AccentInsensitiveIndexOf(string source, string subStr)
        {
            // return CultureInfo.InvariantCulture.CompareInfo.IndexOf(source, subStr, CompareOptions.IgnoreCase | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace);
            var keyword = BoDauTiengViet(subStr);

            //Regex.Match(source, $@"\W{keyword}\W").Index;
            var match = Regex.Match(source, $@"\b{keyword}\b");
            int index = match.Success ? match.Index : -1;
            return index;
        }

       
        public List<(string, int, int)> getListIndexMatch(string source, string subStr)
    {


            var listdata = new List<(string, int, int)>();


            string[] stringSeparators = new string[] { " " };
            var sourceArr = source.Split(stringSeparators, StringSplitOptions.RemoveEmptyEntries);

            var arrKeywork = subStr.Split(stringSeparators, StringSplitOptions.RemoveEmptyEntries);

         

            foreach (string keyword in arrKeywork)
            {
                var start = AccentInsensitiveIndexOf(BoDauTiengViet( source), keyword);
                var end = start + keyword.Length;
                var item = (keyword, start, end);
                if(start >= 0)
                {

                    bool isStartBoundary = (start == 0) || char.IsWhiteSpace(source[start - 1]);
                    bool isEndBoundary = (end == source.Length) || char.IsWhiteSpace(source[end]);

                    //    var stringMatch = source.Substring(start, keyword.Length);

                    //    var isWordMatch = keyword == BoDauTiengViet(stringMatch);
                    //    if (isWordMatch)
                  //  if (isStartBoundary || isEndBoundary) {
                        listdata.Add(item);
                    //}
                   

                }
          

            }
            return listdata;
        }

        public Task<ICollection> QueryAsync(string keywords, CancellationToken cancellation)
        {

            return Task.Run(() =>
            {
                if (!string.IsNullOrEmpty(keywords))
                {
                    return FilterDVHCByKeyWords(listDVHC, keywords) as ICollection;
                }
                else
                {
                    return listDVHC as ICollection;
                }

            });
        }

        private void repositoryItemGridLookUpEdit1_AutoSuggest(object sender, LookUpEditAutoSuggestEventArgs e)
        {
            e.SetMinimumAnimationDuration(TimeSpan.FromMilliseconds(100));
            e.QuerySuggestions = QueryAsync(e.Text, e.CancellationToken);
        }

       
        public List<DVHC> FilterDVHCByKeyWords(List<DVHC> data, string keyworks) {
            string[] pattern_split = new string[] { " " };
            string[] arr_keywords = keyworks.Split(pattern_split, StringSplitOptions.RemoveEmptyEntries);
            var cleanedKeywords = arr_keywords.Select(k => BoDauTiengViet(k));
            var regexPattern = string.Join(".*", cleanedKeywords.Select(Regex.Escape));
            var regex = new Regex(regexPattern, RegexOptions.IgnoreCase);

            return data.Where(item => regex.IsMatch(BoDauTiengViet(item.diadiem))).ToList();
        }

        public string BoDauTiengViet(string str)
        {
            str = str.ToLower().Trim();
            str = Regex.Replace(str, "[àáạảãâầấậẩẫăằắặẳẵ]", "a");
            str = Regex.Replace(str, "[èéẹẻẽêềếệểễ]", "e");
            str = Regex.Replace(str, "[ìíịỉĩ]", "i");
            str = Regex.Replace(str, "[òóọỏõôồốộổỗơờớợởỡ]", "o");
            str = Regex.Replace(str, "[ùúụủũưừứựửữ]", "u");
            str = Regex.Replace(str, "[ỳýỵỷỹ]", "y");
            str = Regex.Replace(str, "đ", "d");
          //  str = Regex.Replace(str, " ", "-");
            str = str.Replace(",", " ");
            str = str.Replace(".", " ");
            return str;
        }

        private void colorForeground_EditValueChanged(object sender, EventArgs e)
        {
            foreColorHighLight = colorForeground.Color;
        }

        private void colorBackground_EditValueChanged(object sender, EventArgs e)
        {
            backgroundColorHighLight = colorBackground.Color;
        }

        private void cb_diadiem_EditValueChanged(object sender, EventArgs e)
        {
            if (cb_diadiem.EditValue != null) {
                
                var selectedRow = cb_diadiem.GetSelectedDataRow() as DVHC; 
                cb_tinhthanh.EditValue = selectedRow.matinh;
                cb_quanhuyen.EditValue = selectedRow.mahuyen;
                cb_phuongxa.EditValue = selectedRow.maxa;
               
            }         

        }
    }



    public class DVHC { 
        public string diadiem { get; set; }
        public string maxa { get; set; }
        public string tenxa { get; set; }
        public string mahuyen { get; set; }
        public string tenhuyen { get; set; }
        public string matinh { get; set; }
        public string tentinh { get; set; }
    }
}

Thanks for watching!

DOWNLOAD SOURCE

THÔNG TIN TÁC GIẢ

BÀI VIẾT LIÊN QUAN

[DEVEXPRESS] Tìm kiếm không dấu tô màu highlight có dấu trên C# Winform
Đăng bởi: Thảo Meo - Lượt xem: 3623 13:57:20, 15/06/2023C#   In bài viết

CÁC BÀI CÙNG CHỦ ĐỀ

Đọc tiếp
.