Using WPF (1)-based on lucene. NET enables ComboBox to have a powerful pull-down Lenovo function lucene. You will also (article 7)-the first quick start to use Lucene. net to achieve full-text search WPF region selection control (included for download)

Source: Internet
Author: User

 

 

I have been wondering how the drop-down Lenovo function of Baidu and Gu Ge search boxes is implemented? Are you constantly querying databases? I don't know how they are so efficient. Later, I had no intention of encountering the "lushen" in the blog Park. The search engine sounds very high. So after studying it for a while, the drop-down Lenovo control of WPF was generated.

Name:

Simple competition:

Full competition:

Area code:

Zip code:

So powerful functional code will be complicated? No ~ The code is just a few words.

The interface is as follows: (the number following the drop-down box is the query delay, and the visible efficiency is still very high)

XAML:

<cop:CopAutoCompleted url="{Binding Text, ElementName=DirTextBox}" columnNames="{Binding Text, ElementName=UCSearchColTextBox}" 
textName="{Binding Text, ElementName=TextNameTextBox}" maxItems="{Binding Text, ElementName=TextNameTextBox_Copy}"> <cop:CopAutoCompleted.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding City}" /> <TextBlock Text=" (" Foreground="#FF383838"/> <TextBlock Text="{Binding Spell}" Foreground="#FF383838" /> <TextBlock Text=")" Foreground="#FF383838"/> </StackPanel> </DataTemplate> </cop:CopAutoCompleted.ItemTemplate> </cop:CopAutoCompleted>

Attribute description: (this control inherits from ComboBox, but has four more attributes)

Url: Set the folder where the index is located (I will introduce how to create the index later)

ColumnNames: Set the name of the column to be retrieved

TextName: select the column name displayed in text after the drop-down list

MaxItems: the maximum number of items displayed in the drop-down box (if there are too many items displayed, there will be latency. The test latency is caused by the change of the data set in the background banding and the new interface, it's not about lucene's efficiency)

ItemTemplate: You can understand it when using WPF. Set the layout of data in the drop-down list. In this way, we have high scalability and flexibility.

 

1. Overall Thinking

(1) create a lucene index: search for a database in a National City on the internet, extract it using code, and create indexes for each column in it.

(2) query index: You can use the lucene PrefixQuery class to construct a query statement to query the entire table by prefix.

(3) ComboBox binding: bind the data source to the ObservableCollection <dynamic> set (automatic notification, convenient ), each item is an object dynamically constructed based on each query result. Therefore, dynamic runtime Parsing is used.

  

 

2. Detailed Design

I will not elaborate on the basic knowledge here. Please refer to the final references in this article.

1. Create a lucene Index

I found a comprehensive Access method when searching for the National Urban database on the Internet, so I specifically wrote the index creation function:

 

(In the past, the general database Access layer was quite popular. I wrote a general database DBHelper Based on reflection. Since there is no database environment on the computer, I only tested Access and Sqlite)

In fact, it is based on the query results to add lucene indexes to the columns for which the index is to be created. The Code is as follows:

View Code

Private void Button_Click_1 (object sender, RoutedEventArgs e) {// set the index folder var directory = FSDirectory. getDirectory (DirTextBox. text, true); // create an index and use StandardAnalyzer to perform sentence segmentation IndexWriter indexWriter = new IndexWriter (directory, new StandardAnalyzer (); var columnName = ColumnNameTextBox. text. split (','); // set the database connection string if (ComboBox1.Text = "Sqlite") {helper = new CopDb. copDbHelper (CopDb. copDbHelper. copDbType. sqlite, ConnTestBox. text);} if (ComboBox1.Text = "Access") {helper = new CopDb. copDbHelper (CopDb. copDbHelper. copDbType. access, ConnTestBox. text);} int timeOut = Environment. tickCount; var read = helper. executeReader (SQLStrTextBox. text); SqlTimeTextBox. text = (Environment. tickCount-timeOut ). toString (); while (read. read () {// create Document doc = new Document (); // Add the field foreach (var item in columnName) {doc. add (new Field (item, read [item]. toString (), Field. store. YES, Field. index. NOT_ANALYZED);} indexWriter. addDocument (doc);} read. close (); // optimize indexWriter for the index file. optimize (); indexWriter. close (); MessageBox. show ("Index created ");}

 

2. query Indexes

  

You can use the PrefixQuery class to construct lucene query, as shown below:

Var cols = SearchColTextBox. text. split (','); BooleanQuery query = new BooleanQuery (); foreach (var item in cols) {query. add (new PrefixQuery (new Term (item, SearchTextBox. text), BooleanClause. occur. shocould);} // query. parse: inject query condition var hits = search. search (query );

 

 

3. Bind a data source to ComboBox

  

The data source is an ObservableCollection <dynamic> type set. In the background, we only need to dynamically construct each query object and add it to the set. ExpandoObject cannot be used when initializing dynamic objects. Although ExpandoObject is convenient, it is a closed class and cannot be inherited. When one of the selected items is displayed in the text box, ComboBox actually executes the ToString () method of the selected data source. Therefore, the ToString () method of ExpandoObject cannot be reloaded. Therefore, a lightweight ExpandoObject class is defined here, inherited from the DynamicObject implementation.

Code:

Class dyData: DynamicObject {public dyData (string colName) {this. public string colName {get; set;} // attribute to be output when colName = colName;} is used to store the attribute name and the corresponding value Dictionary <string, object> data = new Dictionary <string, object> (); // obtain the value of the corresponding attribute public override bool TryGetMember (GetMemberBinder binder, out object result) {return data. tryGetValue (binder. name, out result);} // used to add attributes and the corresponding value public void SetValue (string name, object value) {data. add (name, value) ;}// rewrite Tostring method public override string ToString () {try {return data [colName]. toString ();} catch (Exception ex) {MessageBox. show ("the column name cannot be found" + colName, "An error occurred while setting the name of the item to be displayed in text", MessageBoxButton. OK, MessageBoxImage. error); return null ;}}}

In this way, a simple ExpandoObject is implemented. Next, traverse the query results, use SetValue to dynamically create object attributes, and add them to the ObservableCollection <dynamic> data set. ComboBox can directly bind data.

 

Download: demo

 

References:

Lucene, you will also (7)-First Quick Start

Full-text search using Lucene. Net

WPF region selection control (included)

  

Postscript

In fact, I used the database query method to implement the same function, but it took more than 100 milliseconds each time. Lucene has a cache. The cache speed will get faster and faster, and the priority of frequently searched items will increase.

In my experience, writing an article about the artist is much more concerned and recommended than the logic. I would also like to write down the Blend Artist Series. After all, most of my fans come from this series. However, in recent months, we have been struggling with logic such as WF and WCF, and there is no good idea for art artists.

What are blog posts? It is not just an ordinary coders who want to get more people's attention and approval, which makes me feel that I am actually a little different from migrant workers.

By the way, why can't I see silverlight embedded in my blog? Xap files are all stored in the blogs. Please help me.

  

 

 

 

 

  

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.