I started with creating a string builder object
StringBuilder sb = new StringBuilder();
Next I created a string array to hold the clauses I would eventually turn into my CAML values to test for.
StringCollection andClauses = new StringCollection();
Then, I checked the values of the controls by casting to the type which matched those on the page. I used a switch statement to check the ID of the control. For simplicity I have included only the <And> clauses and a couple of controls. You can extend these to include more using a similar method.
switch (ctl.ID)
{
case "field1":
if(((TextBox)ctl).Text != null && ((TextBox)ctl).Text != "")
{
andClauses.Add("<Eq><FieldRef Name=’field1’/><Value Type='Text'>" + ((TextBox)ctl).Text + "</Value></Eq>");
}
break;
case "field2":
if(((DropDownList)ctl).SelectedValue != null && ((DropDownList)ctl).SelectedValue != "")
{
andClauses.Add("<Eq><FieldRef Name=’field2’/><Value Type='Choice'>" + ((DropDownList)ctl).SelectedValue + "</Value></Eq>");
}
break;
case "field3":
if(((Microsoft.SharePoint.WebControls.DateTimeControl)ctl).IsDateEmpty == false)
{
andClauses.Add("<Geq><FieldRef Name=’field3’/><Value Type='DateTime'>" + Convert.ToDateTime
(((Microsoft.SharePoint.WebControls.DateTimeControl)ctl).SelectedDate).ToShortDateString() + "</Value></Geq>");
}
break;
Notice the casting for the SharePoint controls. In order to get to the value that I need, and to trim the value and remove the time from the DateTimeControl, I have converted the value using the Convert.ToDateTime() method.
After looping through the controls and checking for a value posted, it’s time to now loop through the values and build the CAML string. It is important to note here that a check should be made validating any strings and check for the count of the items. If there is a count of -1 then the loop will produce a wrong output.
Begin by appending the ‘Where’ clause to the string builder. If the item is 1, we do not need to add any ‘And’ clauses.
sb = sb.Append("<Where>");
//only 1 item
if(andClauses.Count == 1)
{
sb = sb.Append(andClauses[0].ToString());
}
When the count is 2, we need to add one ‘And’ clause and add both item to be searched for.
//two items
else if(andClauses.Count == 2)
{
sb = sb.Append("<And>" + andClauses[0].ToString() + andClauses[1].ToString() + "</And>");
}
When the item count is greater than 2, we will add the ‘And’ clauses based on the count – 1.
else if(andClauses.Count > 2)
{
for(int i = andClauses.Count - 1; i > 0; i--)
{
sb = sb.Append("<And>");
}
After adding the proper number of clauses we will add the first two items and close the first ‘And’ clause off. Then, as we loop through the remaining items, we add another ‘And’ clause after each iteration and close then set. If you were to add ‘Or’ clauses, you could do the same.
sb = sb.Append(andClauses[0].ToString() + andClauses[1].ToString() + "</And>");
for(int j = 2; j < andClauses.Count; j++)
{
sb = sb.Append(andClauses[j].ToString() + "</And>");
}
}
Finally we close the entire set off by adding the closing ‘Where’ clause.
sb = sb.Append("</Where>");
What you should have is a structure that is properly built to issue the query against the list. As mentioned before, this will work for any number of items and is not limited to the ‘And’ element. When building the array you can add additional checks, such as a comparison of ‘Or’, whereby you can test for additional parameters passed into the above loops and build an even more complex structure.