您的位置:首页 > 其它

WPF-002 下拉列表的简单实现

2012-11-13 11:38 323 查看
最近在一个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>
效果:



主要注意的有一点,下拉列表消失时一定要清除数据,不然下次显示的时候会很慢。在用的时候找了好久才发现这个问题。
详细工程:http://download.csdn.net/detail/yysyangyangyangshan/4762184
本文出自 “西北白杨树” 博客,请务必保留此出处http://yangyoushan.blog.51cto.com/7229571/1276442
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: