首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

WPF:上拉列表的简单实现

2012-11-23 
WPF:下拉列表的简单实现最近在一个WPF项目中用到一个下拉列表,随着用户输入字符而进行显示,使用了绑定等知

WPF:下拉列表的简单实现

最近在一个WPF项目中用到一个下拉列表,随着用户输入字符而进行显示,使用了绑定等知识,虽然实现比较简单,可是在性能上也是想了很多办法终于才勉强可以用,与大家分享下。

用于页面绑定的模型类:

public class MainWindowModel : INotifyPropertyChanged    {        public event PropertyChangedEventHandler PropertyChanged;        private ObservableCollection<Content> names = new ObservableCollection<Content>();        private bool popupIsOpen = false;        public bool PopupIsOpen        {            get             {                 return popupIsOpen;            }            set             {                 popupIsOpen = value;                this.PropertyChanged(this, new PropertyChangedEventArgs("PopupIsOpen"));            }        }        public ObservableCollection<Content> Names        {            get            {                return this.names;            }            set            {                this.names = value;                this.PropertyChanged(this, new PropertyChangedEventArgs("Names"));            }        }    }    public class Content    {        private string name=string.Empty;        public string Name        {            get            {                return this.name;            }            set            {                name = value;            }        }    }

后台代码:

 /// <summary>    /// MainWindow.xaml 的交互逻辑    /// </summary>    public partial class MainWindow : Window    {        private MainWindowModel model = new MainWindowModel();        private List<BackgroundWorker> threadPool = new List<BackgroundWorker>();        public MainWindow()        {            InitializeComponent();            this.DataContext = model;        }        /// <summary>        /// 在此增加内容        /// </summary>        private void InitialSetValue()        {            this.Dispatcher.BeginInvoke(new Action(() =>                {                    this.model.Names.Clear();                    for (int i = 0; i < 100; i++)                    {                        Content content = new Content();                        content.Name = i.ToString() + i.ToString() +                             i.ToString() + i.ToString() + i.ToString();                        this.model.Names.Add(content);                    }                }));        }        /// <summary>        /// 下拉菜单消失要清空内容        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void popupContent_Closed(object sender, EventArgs e)        {            this.model.Names.Clear();        }        /// <summary>        /// 文本框失去焦点,下拉列表隐藏        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void textBox1_LostFocus(object sender, RoutedEventArgs e)        {            this.model.PopupIsOpen = false;        }        /// <summary>        /// 文字内容改变,下拉类表出现        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void textBox1_TextChanged(object sender, TextChangedEventArgs e)        {            this.model.PopupIsOpen = true;            if (threadPool.Count > 0)            {                threadPool[0].CancelAsync();            }            threadPool.Clear();            string key = this.textBox1.Text.Trim();            if (string.IsNullOrEmpty(key))            {                this.model.PopupIsOpen = false;                return;            }            BackgroundWorker worker = new BackgroundWorker();            worker.WorkerReportsProgress = true;            worker.WorkerSupportsCancellation = true;            worker.DoWork += (o, p) =>            {                InitialSetValue();                p.Result = this.model.Names;            };            worker.RunWorkerCompleted += (o, p) =>            {                this.model.Names = p.Result as ObservableCollection<Content>;                if (this.model.Names.Count <= 0)                {                    this.model.PopupIsOpen = false;                }            };            threadPool.Add(worker);            Thread.Sleep(100);            if (threadPool.Count > 0)            {                threadPool[0].RunWorkerAsync();            }        }        /// <summary>        /// 子项被选中,下拉列表消失        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void item_SelectionChanged(object sender, SelectionChangedEventArgs e)        {            var data = (sender as ListBox).SelectedItem as Content;            if (data == null)            {                this.model.PopupIsOpen = false;                return;            }            try            {                this.textBox1.TextChanged -= new TextChangedEventHandler(textBox1_TextChanged);                var searchtext = data.Name;                this.model.PopupIsOpen = false;            }            catch            {            }            finally            {                this.textBox1.TextChanged += new TextChangedEventHandler(textBox1_TextChanged);            }        }    }

页面代码:

 <Window x:Class="TestPopup.MainWindow"        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        Title="MainWindow" Height="350" Width="525">    <Grid>        <TextBox Height="38" HorizontalAlignment="Left" Margin="71,89,0,0" LostFocus="textBox1_LostFocus" TextChanged="textBox1_TextChanged"                 Name="textBox1" VerticalAlignment="Top" Width="236" />                <Popup Name="popupContent" StaysOpen="False" IsOpen="{Binding PopupIsOpen}" Closed="popupContent_Closed"               Placement="Bottom"  PlacementTarget="{Binding ElementName=textBox1}"  >                        <ListBox Name="contentItems" SelectionChanged="item_SelectionChanged"   ItemsSource="{Binding Names}"                                 MinWidth="{Binding ElementName=textBox1, Path=ActualWidth}">                <ListBox.ItemTemplate>                    <DataTemplate>                        <TextBlock Margin="5,5" FontSize="15" Text="{Binding Name}" Foreground="Gray"/>                    </DataTemplate>                </ListBox.ItemTemplate>            </ListBox>        </Popup>    </Grid></Window>

效果:
WPF:上拉列表的简单实现

主要注意的有一点,下拉列表消失时一定要清除数据,不然下次显示的时候会很慢。在用的时候找了好久才发现这个问题。
详细工程:http://download.csdn.net/detail/yysyangyangyangshan/4762184

热点排行