CodeProjectSearch[Beginner]
Introduction
Welcome my name is Charles Henington and today I will be offereing a short tutorial on a CodeProject search tool That I have created.
Background
while browsing many of the questions here in the Code Project Questions Boards. We notice that many questions which are asked could easily be found by searching Google or Code Project. By the end of this tutorial I hope you to understand a little more about stucts, XmlDocuments, XmlDocuments, and switches. First we will take a look at the largest struct this struct is called SearchTerm and we have a string nested with this struct and nested within this string is an xmlDocument and a switch statement. lets have a look at this now. Also keep in mind the XmlDocument and switch statement is actually larger than actually needed at the moment. The switch on each switch has a if,else if, else statement which returns 3 different senarios, the reason for this being is i dont want to in and rewrite the code every time a site changes there search criteria So by adding a small change to the Xml I can simply rewite the xml file to accommodate the changes. Ok...Ok... I Know enough talk let's se some code.
Using the code
The Only uising Statements that we will use throught the Entire Project(Besides designer generated) areusing System;
using System.Xml;
using System.Windows.Forms;
using System;
using System.Xml;
namespace CodeProjectSearch
{
internal struct SearchTerm
{
internal const string xPathPart = "/CodeProject/";
internal const string SearchAttribute = "Url";
internal const string iParts = "Parts";
internal static string SearchString(string term, SearchMethod method)
{
XmlDocument SearchDoc = new XmlDocument();
SearchDoc.Load(CodeProject.SettingsDocument);
int AnswerParts = Int32.Parse(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.Answers.ToString()).Attributes[iParts].InnerText);
int ArticleParts = Int32.Parse(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.Articles.ToString()).Attributes[iParts].InnerText);
int CatalogItemsParts = Int32.Parse(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.CatalogItems.ToString()).Attributes[iParts].InnerText);
int EverythingParts = Int32.Parse(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.Everything.ToString()).Attributes[iParts].InnerText);
int JustYoursParts = Int32.Parse(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.JustYours.ToString()).Attributes[iParts].InnerText);
int MessagesParts = Int32.Parse(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.Messages.ToString()).Attributes[iParts].InnerText);
int NewsItemsParts = Int32.Parse(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.NewsItems.ToString()).Attributes[iParts].InnerText);
int QuestionsParts = Int32.Parse(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.Questions.ToString()).Attributes[iParts].InnerText);
int TechnicalBlogsParts = Int32.Parse(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.TechnicalBlogs.ToString()).Attributes[iParts].InnerText);
int TipsTricksParts = Int32.Parse(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.TipsTricks.ToString()).Attributes[iParts].InnerText);
int YourBookMarksParts = Int32.Parse(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.YourBookMarks.ToString()).Attributes[iParts].InnerText);
string search = null;
switch(method)
{
case SearchMethod.Answers:
if (AnswerParts == 1)
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.Answers.ToString()).Attributes[SearchAttribute].InnerText, term);
}
else if (AnswerParts == 2)
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.Answers.ToString()).Attributes[SearchAttribute].InnerText, term, term);
}
else
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.Answers.ToString()).Attributes[SearchAttribute].InnerText, term, term, term);
}
break;
case SearchMethod.Articles:
default:
if (ArticleParts == 1)
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.Articles.ToString()).Attributes[SearchAttribute].InnerText, term);
}
else if (ArticleParts == 2)
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.Articles.ToString()).Attributes[SearchAttribute].InnerText, term, term);
}
else
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.Articles.ToString()).Attributes[SearchAttribute].InnerText, term, term, term);
}
break;
case SearchMethod.CatalogItems:
if (CatalogItemsParts == 1)
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.CatalogItems.ToString()).Attributes[SearchAttribute].InnerText, term);
}
else if (CatalogItemsParts == 2)
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.CatalogItems.ToString()).Attributes[SearchAttribute].InnerText, term, term);
}
else
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.CatalogItems.ToString()).Attributes[SearchAttribute].InnerText, term, term, term);
}
break;
case SearchMethod.Everything:
if (EverythingParts == 1)
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.Everything.ToString()).Attributes[SearchAttribute].InnerText, term);
}
else if (EverythingParts == 2)
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.Everything.ToString()).Attributes[SearchAttribute].InnerText, term, term);
}
else
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.Everything.ToString()).Attributes[SearchAttribute].InnerText, term, term, term);
}
break;
case SearchMethod.JustYours:
if (JustYoursParts == 1)
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.JustYours.ToString()).Attributes[SearchAttribute].InnerText, term);
}
else if (JustYoursParts == 2)
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.JustYours.ToString()).Attributes[SearchAttribute].InnerText, term, term);
}
else
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.JustYours.ToString()).Attributes[SearchAttribute].InnerText, term, term, term);
}
break;
case SearchMethod.Messages:
if (MessagesParts == 1)
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.Messages.ToString()).Attributes[SearchAttribute].InnerText, term);
}
else if (MessagesParts == 2)
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.Messages.ToString()).Attributes[SearchAttribute].InnerText, term, term);
}
else
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.Messages.ToString()).Attributes[SearchAttribute].InnerText, term, term, term);
}
break;
case SearchMethod.NewsItems:
if (NewsItemsParts == 1)
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.NewsItems.ToString()).Attributes[SearchAttribute].InnerText, term);
}
else if (NewsItemsParts == 2)
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.NewsItems.ToString()).Attributes[SearchAttribute].InnerText, term, term);
}
else
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.NewsItems.ToString()).Attributes[SearchAttribute].InnerText, term, term, term);
}
break;
case SearchMethod.Questions:
if (QuestionsParts == 1)
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.Questions.ToString()).Attributes[SearchAttribute].InnerText, term);
}
else if (QuestionsParts == 2)
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.Questions.ToString()).Attributes[SearchAttribute].InnerText, term, term);
}
else
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.Questions.ToString()).Attributes[SearchAttribute].InnerText, term, term, term);
}
break;
case SearchMethod.TechnicalBlogs:
if (TechnicalBlogsParts == 1)
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.TechnicalBlogs.ToString()).Attributes[SearchAttribute].InnerText, term);
}
else if (TechnicalBlogsParts == 2)
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.TechnicalBlogs.ToString()).Attributes[SearchAttribute].InnerText, term, term);
}
else
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.TechnicalBlogs.ToString()).Attributes[SearchAttribute].InnerText, term, term, term);
}
break;
case SearchMethod.TipsTricks:
if (TipsTricksParts == 1)
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.TipsTricks.ToString()).Attributes[SearchAttribute].InnerText, term);
}
else if (TipsTricksParts == 2)
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.TipsTricks.ToString()).Attributes[SearchAttribute].InnerText, term, term);
}
else
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.TipsTricks.ToString()).Attributes[SearchAttribute].InnerText, term, term, term);
}
break;
case SearchMethod.YourBookMarks:
if (YourBookMarksParts == 1)
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.YourBookMarks.ToString()).Attributes[SearchAttribute].InnerText, term);
}
else if (YourBookMarksParts == 2)
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.YourBookMarks.ToString()).Attributes[SearchAttribute].InnerText, term, term);
}
else
{
search = String.Format(SearchDoc.SelectSingleNode(xPathPart + SearchMethod.YourBookMarks.ToString()).Attributes[SearchAttribute].InnerText, term, term, term);
}
break;
}
return search;
}
}
}
Now that we have this class You will notice that our switch statement switches between our SearchMethod enum. The Code for this looks like this.
using System;
namespace CodeProjectSearch
{
public enum SearchMethod
{
Answers,
Articles,
Everything,
CatalogItems,
JustYours,
Messages,
NewsItems,
Questions,
TechnicalBlogs,
TipsTricks,
YourBookMarks
}
}
Nice Small little .cs file doesnt take up much room :) Now to get the two classes to work together to retrive our search link to load in our browser we have a few other small little .cs files. I could have made this class call it directly but I wanted to call as an object in a way to show you a nice way to call and enum via Enum.Parse. and here is the object struct.
using System;
namespace CodeProjectSearch
{
internal struct SearchMethodObject
{
internal static SearchMethod NewSearchMethod(Object obj)
{
return (SearchMethod)obj;
}
}
}
Now that we have our enum coreectly converted to an object it's time to put our large .cs switch struct slash string and our SearchMethod Object Together to create our url. Here is the code to do just that.
using System;
namespace CodeProjectSearch
{
public struct CodeProjectUrl
{
public static string Get(string term, Object obj)
{
return SearchTerm.SearchString(term, SearchMethodObject.NewSearchMethod(obj));
}
}
}
Now then our url is constructed and all we have to do is call webrowser1.Navigate("url to navigate to"); but I have never been a fan of calling webbrowser1.Navigate so I have a small little trick I would like to share. First click on your WebBrowser control and look in the properties for a setting called modifiers and change it to internal. this property allows you to set the visiblity of a control[Note by default Controls visibility are set to private] YOU NEVER WANT TO SET A CONTROL'S VISIBILITY TO PUBLIC!! This open's the Control up to using outside of your application which makes you application weak to security and virus threats, when internal the control is accessible from whithin the application over other forms but not outside of your application. Now comes the tricky part look for the code in Form1 by default but my main form is MainForm Look for code in MainForm.Designer.cs that reads internal WebBrowser webBrowser1 and change to internal static Webbrowser webBrowser1. Now that this is done you will notice that the designer is showing errors, this is because this and base cannot be called within a static or absract class or on a static control, so all we have to do is remove this. from this.webBrowser1 anywhere it appears in our code. Now that this is done add a class the name that I have choosen is CodeProject once the .cs file shows change public class CodeProject {} to public abstract class CodeProject : MainForm { } then we will create a void a static void in this class for our webBrowser1.Navigate command. and this is what it will look like
using System;
using System.Windows.Forms;
namespace CodeProjectSearch
{
public abstract class CodeProject : MainForm
{
internal static readonly string SettingsDocument = Application.StartupPath + @"\CodeSearch.xml";
public static void GoSearch(string term, Object obj)
{
SearchNavigator.Navigate(CodeProjectUrl.Get(term, obj));
}
}
}
now from our MainForm We would call the method as such
CodeProject.GoSearch(SearchBox.Text, Enum.Parse((typeof(SearchMethod)), "Articles"));
Quick Point: You can use Enum.Parse on any enum :) like this
public Keys KeyBoard_Key()
{
// returns the A Key
return (Keys)Enum.Parse((typeof(Keys)),"A");
}
Points of Interest
Did You Learn anything interesteing, anything you would like to share, Please feel free to leave a comment or questions below and I will get back to you.
History
2011, Tuesday May 3 Initial Post