123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- using Avalonia.Controls;
- using Avalonia.LogicalTree;
- using Avalonia.Markup.Xaml;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading;
- using System.Threading.Tasks;
- using Avalonia.Data.Converters;
- using Avalonia.Data;
- using ControlCatalog.Models;
- namespace ControlCatalog.Pages
- {
- public class AutoCompleteBoxPage : UserControl
- {
- private StateData[] BuildAllStates()
- {
- return new StateData[]
- {
- new StateData("Alabama","AL","Montgomery"),
- new StateData("Alaska","AK","Juneau"),
- new StateData("Arizona","AZ","Phoenix"),
- new StateData("Arkansas","AR","Little Rock"),
- new StateData("California","CA","Sacramento"),
- new StateData("Colorado","CO","Denver"),
- new StateData("Connecticut","CT","Hartford"),
- new StateData("Delaware","DE","Dover"),
- new StateData("Florida","FL","Tallahassee"),
- new StateData("Georgia","GA","Atlanta"),
- new StateData("Hawaii","HI","Honolulu"),
- new StateData("Idaho","ID","Boise"),
- new StateData("Illinois","IL","Springfield"),
- new StateData("Indiana","IN","Indianapolis"),
- new StateData("Iowa","IA","Des Moines"),
- new StateData("Kansas","KS","Topeka"),
- new StateData("Kentucky","KY","Frankfort"),
- new StateData("Louisiana","LA","Baton Rouge"),
- new StateData("Maine","ME","Augusta"),
- new StateData("Maryland","MD","Annapolis"),
- new StateData("Massachusetts","MA","Boston"),
- new StateData("Michigan","MI","Lansing"),
- new StateData("Minnesota","MN","St. Paul"),
- new StateData("Mississippi","MS","Jackson"),
- new StateData("Missouri","MO","Jefferson City"),
- new StateData("Montana","MT","Helena"),
- new StateData("Nebraska","NE","Lincoln"),
- new StateData("Nevada","NV","Carson City"),
- new StateData("New Hampshire","NH","Concord"),
- new StateData("New Jersey","NJ","Trenton"),
- new StateData("New Mexico","NM","Santa Fe"),
- new StateData("New York","NY","Albany"),
- new StateData("North Carolina","NC","Raleigh"),
- new StateData("North Dakota","ND","Bismarck"),
- new StateData("Ohio","OH","Columbus"),
- new StateData("Oklahoma","OK","Oklahoma City"),
- new StateData("Oregon","OR","Salem"),
- new StateData("Pennsylvania","PA","Harrisburg"),
- new StateData("Rhode Island","RI","Providence"),
- new StateData("South Carolina","SC","Columbia"),
- new StateData("South Dakota","SD","Pierre"),
- new StateData("Tennessee","TN","Nashville"),
- new StateData("Texas","TX","Austin"),
- new StateData("Utah","UT","Salt Lake City"),
- new StateData("Vermont","VT","Montpelier"),
- new StateData("Virginia","VA","Richmond"),
- new StateData("Washington","WA","Olympia"),
- new StateData("West Virginia","WV","Charleston"),
- new StateData("Wisconsin","WI","Madison"),
- new StateData("Wyoming","WY","Cheyenne"),
- };
- }
- public StateData[] States { get; private set; }
-
- private LinkedList<string>[] BuildAllSentences()
- {
- return new string[]
- {
- "Hello world",
- "No this is Patrick",
- "Never gonna give you up",
- "How does one patch KDE2 under FreeBSD"
- }
- .Select(x => new LinkedList<string>(x.Split(' ')))
- .ToArray();
- }
- public LinkedList<string>[] Sentences { get; private set; }
- public AutoCompleteBoxPage()
- {
- this.InitializeComponent();
- States = BuildAllStates();
- Sentences = BuildAllSentences();
- foreach (AutoCompleteBox box in GetAllAutoCompleteBox().Where(x => x.Name != "CustomAutocompleteBox"))
- {
- box.Items = States;
- }
- var converter = new FuncMultiValueConverter<string, string>(parts =>
- {
- return String.Format("{0} ({1})", parts.ToArray());
- });
- var binding = new MultiBinding { Converter = converter };
- binding.Bindings.Add(new Binding("Name"));
- binding.Bindings.Add(new Binding("Abbreviation"));
- var multibindingBox = this.Get<AutoCompleteBox>("MultiBindingBox");
- multibindingBox.ValueMemberBinding = binding;
- var asyncBox = this.Get<AutoCompleteBox>("AsyncBox");
- asyncBox.AsyncPopulator = PopulateAsync;
- var customAutocompleteBox = this.Get<AutoCompleteBox>("CustomAutocompleteBox");
- customAutocompleteBox.Items = Sentences.SelectMany(x => x);
- customAutocompleteBox.TextFilter = LastWordContains;
- customAutocompleteBox.TextSelector = AppendWord;
- }
- private IEnumerable<AutoCompleteBox> GetAllAutoCompleteBox()
- {
- return
- this.GetLogicalDescendants()
- .OfType<AutoCompleteBox>();
- }
- private bool StringContains(string str, string? query)
- {
- if (query == null) return false;
- return str.IndexOf(query, StringComparison.OrdinalIgnoreCase) >= 0;
- }
- private async Task<IEnumerable<object>> PopulateAsync(string? searchText, CancellationToken cancellationToken)
- {
- await Task.Delay(TimeSpan.FromSeconds(1.5), cancellationToken);
- return
- States.Where(data => StringContains(data.Name, searchText) || StringContains(data.Capital, searchText))
- .ToList();
- }
- private bool LastWordContains(string? searchText, string? item)
- {
- var words = searchText?.Split(' ') ?? Array.Empty<string>();
- var options = Sentences.Select(x => x.First)
- .ToArray<LinkedListNode<string>?>();
- for (var i = 0; i < words.Length; ++i)
- {
- var word = words[i];
- for (var j = 0; word is { } && j < options.Length; ++j)
- {
- if (options[i] is { } option)
- {
- if (i == words.Length - 1)
- {
- options[j] = option.Value.ToLower().Contains(word.ToLower()) ? option : null;
- }
- else
- {
- options[j] = option.Value.Equals(word, StringComparison.InvariantCultureIgnoreCase) ? option.Next : null;
- }
- }
- }
- }
- return options.Any(x => x != null && x.Value == item);
- }
- private string AppendWord(string? text, string? item)
- {
- if (item is { })
- {
- string[] parts = text?.Split(' ') ?? Array.Empty<string>();
- if (parts.Length == 0)
- return item;
- parts[parts.Length - 1] = item;
- return string.Join(" ", parts);
- }
- return string.Empty;
- }
- private void InitializeComponent()
- {
- AvaloniaXamlLoader.Load(this);
- }
- }
- }
|