zoukankan      html  css  js  c++  java
  • WPF 之 实现TextBox输入文字后自动弹出数据(类似百度的输入框)

    1、添加一个数据实体类 AutoCompleteEntry,如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace FCClient.AppCode
    {
        public class AutoCompleteEntry
        {
            private string[] keywordStrings;
            private string displayString;
    
            public string[] KeywordStrings
            {
                get
                {
                    if (keywordStrings == null)
                    {
                        keywordStrings = new string[] { displayString };
                    }
                    return keywordStrings;
                }
            }
    
            public string DisplayName
            {
                get { return displayString; }
                set { displayString = value; }
            }
    
            public AutoCompleteEntry(string name, params string[] keywords)
            {
                displayString = name;
                keywordStrings = keywords;
            }
    
            public override string ToString()
            {
                return displayString;
            }
        }
    }

    2、创建一个继承至Canvas的控件,并命名为AutoCompleteTextBox,前台 AutoCompleteTextBox.xam l代码,如下:

    <Canvas x:Class="FCClient.CustomControls.AutoCompleteTextBox"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="30" Width="300">
    </Canvas>

    3、后台 AutoCompleteTextBox 代码,如下:

    using System;
    using System.Collections.ObjectModel;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Timers;
    
    using FCClient.AppCode;
    
    namespace FCClient.CustomControls
    {
        /// <summary>
        /// 自定义自动匹配文本框
        /// </summary>    
        public partial class AutoCompleteTextBox : Canvas
        {
            #region 成员变量
    
            private VisualCollection controls;
            private TextBox textBox;
            private ComboBox comboBox;
            private ObservableCollection<AutoCompleteEntry> autoCompletionList;
            private Timer keypressTimer;
            private delegate void TextChangedCallback();
            private bool insertText;
            private int delayTime;
            private int searchThreshold;
    
            #endregion 成员变量
    
            #region 构造函数
    
            public AutoCompleteTextBox()
            {
                controls = new VisualCollection(this);
                InitializeComponent();
    
                autoCompletionList = new ObservableCollection<AutoCompleteEntry>();
                searchThreshold = 0;        // default threshold to 2 char
                delayTime = 100;
    
                // set up the key press timer
                keypressTimer = new System.Timers.Timer();
                keypressTimer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimedEvent);
    
                // set up the text box and the combo box
                comboBox = new ComboBox();
                comboBox.IsSynchronizedWithCurrentItem = true;
                comboBox.IsTabStop = false;
                Panel.SetZIndex(comboBox, -1);
                comboBox.SelectionChanged += new SelectionChangedEventHandler(comboBox_SelectionChanged);
    
                textBox = new TextBox();
                textBox.TextChanged += new TextChangedEventHandler(textBox_TextChanged);
                textBox.GotFocus += new RoutedEventHandler(textBox_GotFocus);
                textBox.KeyUp += new KeyEventHandler(textBox_KeyUp);
                textBox.KeyDown += new KeyEventHandler(textBox_KeyDown);
                textBox.VerticalContentAlignment = VerticalAlignment.Center;
    
                controls.Add(comboBox);
                controls.Add(textBox);
            }
    
            #endregion 构造函数
    
            #region 成员方法
    
            public string Text
            {
                get { return textBox.Text; }
                set
                {
                    insertText = true;
                    textBox.Text = value;
                }
            }
    
            public int DelayTime
            {
                get { return delayTime; }
                set { delayTime = value; }
            }
    
            public int Threshold
            {
                get { return searchThreshold; }
                set { searchThreshold = value; }
            }
    
            /// <summary>
            /// 添加Item
            /// </summary>
            /// <param name="entry"></param>
            public void AddItem(AutoCompleteEntry entry)
            {
                autoCompletionList.Add(entry);
            }
    
            /// <summary>
            /// 清空Item
            /// </summary>
            /// <param name="entry"></param>
            public void ClearItem()
            {
                autoCompletionList.Clear();
            }
    
            private void comboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                if (null != comboBox.SelectedItem)
                {
                    insertText = true;
                    ComboBoxItem cbItem = (ComboBoxItem)comboBox.SelectedItem;
                    textBox.Text = cbItem.Content.ToString();
                }
            }
    
            private void TextChanged()
            {
                try
                {
                    comboBox.Items.Clear();
                    if (textBox.Text.Length >= searchThreshold)
                    {
                        foreach (AutoCompleteEntry entry in autoCompletionList)
                        {
                            foreach (string word in entry.KeywordStrings)
                            {
                                if (word.Contains(textBox.Text))
                                {
                                    ComboBoxItem cbItem = new ComboBoxItem();
                                    cbItem.Content = entry.ToString();
                                    comboBox.Items.Add(cbItem);
                                    break;
                                }
                                //if (word.StartsWith(textBox.Text, StringComparison.CurrentCultureIgnoreCase))
                                //{
                                //    ComboBoxItem cbItem = new ComboBoxItem();
                                //    cbItem.Content = entry.ToString();
                                //    comboBox.Items.Add(cbItem);
                                //    break;
                                //}
                            }
                        }
                        comboBox.IsDropDownOpen = comboBox.HasItems;
                    }
                    else
                    {
                        comboBox.IsDropDownOpen = false;
                    }
                }
                catch { }
            }
    
            private void OnTimedEvent(object source, System.Timers.ElapsedEventArgs e)
            {
                keypressTimer.Stop();
                Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal,
                    new TextChangedCallback(this.TextChanged));
            }
    
            private void textBox_TextChanged(object sender, TextChangedEventArgs e)
            {
                // text was not typed, do nothing and consume the flag
                if (insertText == true) insertText = false;
    
                // if the delay time is set, delay handling of text changed
                else
                {
                    if (delayTime > 0)
                    {
                        keypressTimer.Interval = delayTime;
                        keypressTimer.Start();
                    }
                    else TextChanged();
                }
            }
    
            //获得焦点时
            public void textBox_GotFocus(object sender, RoutedEventArgs e)
            {
                // text was not typed, do nothing and consume the flag
                if (insertText == true) insertText = false;
    
                // if the delay time is set, delay handling of text changed
                else
                {
                    if (delayTime > 0)
                    {
                        keypressTimer.Interval = delayTime;
                        keypressTimer.Start();
                    }
                    else TextChanged();
                }
            }
    
            public void textBox_KeyDown(object sender, KeyEventArgs e)
            {
                if (textBox.IsInputMethodEnabled == true)
                {
                    comboBox.IsDropDownOpen = false;
                }
            }
    
            /// <summary>
            /// 按向下按键时
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            public void textBox_KeyUp(object sender, KeyEventArgs e)
            {
                if (e.Key == Key.Down && comboBox.IsDropDownOpen == true)
                {
                    comboBox.Focus();
                }
            }
    
            protected override Size ArrangeOverride(Size arrangeSize)
            {
                textBox.Arrange(new Rect(arrangeSize));
                comboBox.Arrange(new Rect(arrangeSize));
                return base.ArrangeOverride(arrangeSize);
            }
    
            protected override Visual GetVisualChild(int index)
            {
                return controls[index];
            }
    
            protected override int VisualChildrenCount
            {
                get { return controls.Count; }
            }
    
            #endregion 成员方法
        }
    }

    4.、使用创建的 AutoCompleteTextbox ,新建一个WPF工程,在Windows1.xaml 中添加自定义的控件,如下:

    <Window x:Class="WPFAutoCompleteTextbox.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WPFAutoCompleteTextbox"        
        Title="WPF AutoCompleteTextBox" Height="195" Width="561">
        <Grid Background="SteelBlue">
            <Button Name="button1" Height="23" Width="75" Margin="12,12,0,0" Click="button1_Click" 
             HorizontalAlignment
    ="Left" VerticalAlignment="Top">Clear</Button> <local:AutoCompleteTextBox Height="23" Width="162" x:Name="textBox1" Margin="25,65,0,0"
              HorizontalAlignment
    ="Left" VerticalAlignment="Top" /> </Grid> </Window>

    5、 在 Windows1.cs 中初始化搜索数据,如下:

        public partial class Window1 : Window
        {
            public Window1()
            {
                InitializeComponent();
                textBox1.AddItem(new AutoCompleteEntry("上海", null));
                textBox1.AddItem(new AutoCompleteEntry("北京", null));
                textBox1.AddItem(new AutoCompleteEntry("济南", null));
                textBox1.AddItem(new AutoCompleteEntry("青岛", null));
                textBox1.AddItem(new AutoCompleteEntry("天津", null));
                textBox1.AddItem(new AutoCompleteEntry("黑龙江", null));
                textBox1.AddItem(new AutoCompleteEntry("聊城", null));
            }
    
            private void button1_Click(object sender, RoutedEventArgs e)
            {
                textBox1.Text = string.Empty;
            }
        }
  • 相关阅读:
    usb3.0 bMaxBurst最大支持多少个 这个描述符什么时候被读取
    盒式图|加置信椭圆的散点图|分组盒式图|分组散点图|马赛克图|
    协方差分析|随机区组设计|样本单位|样本容量|变异系数|片面误差|抽样误差|真实性|精密度|重复性|精确程度|计数数据|区间变量|离散型变量|数值变量
    试验指标|试验单位|均方|随机模型|固定模型|字母标记法|LSR|q检验|LSD|重复值|弥补缺失数据|可加性|平方根转换|对数转换|反正弦转化
    2×c列联表|多组比例简式|卡方检验|χ2检验与连续型资料假设检验
    显著水平|区间估计|假设检验|显著性|第一类错误|Ⅱ类错误|β错误|t检验|连续性矫正|二项分布的假设检验|样本百分率|
    估计量|估计值|矩估计|最大似然估计|无偏性|无偏化|有效性|置信区间|枢轴量|似然函数|伯努利大数定理|t分布|单侧置信区间|抽样函数|
    单因素方差分析
    左偏|有偏|中心极限定理|卡方分布|
    正交试验
  • 原文地址:https://www.cnblogs.com/xinaixia/p/5549843.html
Copyright © 2011-2022 走看看