<?xml version="1.0" encoding="UTF-8" ?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><title type="html">Moving From One Task To The Next...</title><subtitle type="html">A series of unrelated Workflow topics in no particular order</subtitle><id>http://www.captaris.com/DeveloperProgram/blogs/doncampbell_blog/atom.aspx</id><link rel="alternate" type="text/html" href="http://www.captaris.com/DeveloperProgram/blogs/doncampbell_blog/default.aspx" /><link rel="self" type="application/atom+xml" href="http://www.captaris.com/DeveloperProgram/blogs/doncampbell_blog/atom.aspx" /><generator uri="http://communityserver.org" version="2.0.60217.2664">Community Server</generator><updated>2007-05-22T09:39:00Z</updated><entry><title>Search Your TaskList By Date</title><link rel="alternate" type="text/html" href="http://www.captaris.com/DeveloperProgram/blogs/doncampbell_blog/archive/2007/06/14/12540.aspx" /><id>http://www.captaris.com/DeveloperProgram/blogs/doncampbell_blog/archive/2007/06/14/12540.aspx</id><published>2007-06-14T16:23:00Z</published><updated>2007-06-14T16:23:00Z</updated><content type="html">&lt;p&gt;In &lt;em&gt;&lt;a href="/DeveloperProgram/blogs/doncampbell_blog/archive/2007/05/31/12514.aspx"&gt;&amp;lt;my last post/&amp;gt;&lt;/a&gt;&lt;/em&gt; I explained how you might add a search bar to your TaskList. I'm going to follow up with another sample that demonstrates how to build a search bar that selects tasks by date. To make selecting a date for my sample easy to do, I've decided to use &lt;em&gt;&lt;a href="http://www.dynarch.com/projects/calendar/"&gt;&amp;lt;The Coolest DHTML / JavaScript Calendar/&amp;gt;&lt;/a&gt;&lt;/em&gt; that I could find.&lt;/p&gt;

&lt;img alt="Search By Date" src="/developerprogram/themes/default/images/SearchByDate.jpg"&gt;
&lt;br class="clear"&gt;&lt;br&gt;

&lt;p&gt;The first thing I’m going to do is add the following ASP.NET controls to the form tag within my web page.&lt;/p&gt;

&lt;div class="code"&gt;&lt;pre&gt;&amp;lt;div style="margin: 6px 0;"&amp;gt;&lt;br&gt;    &amp;lt;asp:dropdownlist id="columnsDropDownList" runat="server" /&amp;gt;&lt;br&gt;    &amp;lt;asp:dropdownlist id="commandsDropDownList" runat="server" /&amp;gt;&lt;br&gt;    &amp;lt;asp:textbox id="date" runat="server" /&amp;gt;&lt;br&gt;    &amp;lt;script type="text/javascript"&amp;gt;&lt;br&gt;        Calendar.setup({&lt;br&gt;            inputField  : "date",       // id of the input field&lt;br&gt;            ifFormat    : "%m/%d/%Y",   // format of the input field&lt;br&gt;            showsTime   : false,&lt;br&gt;            singleClick : true&lt;br&gt;        });&lt;br&gt;    &amp;lt;/script&amp;gt;&lt;br&gt;    &amp;lt;asp:button id="searchButton" runat="server" text="Search" /&amp;gt;&lt;br&gt;&amp;lt;/div&amp;gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br class="clear"&gt;

&lt;p&gt;I am going to use the DropDownList controls to display the columns
and operators the user selects to match the date they pick from the popup calendar associated with the TextBox control. The Button control is used to kick off the search.&lt;/p&gt;

&lt;p&gt;To get the Calendar control to work, you need to add the following lines to the head tag.&lt;/p&gt;

&lt;div class="code"&gt;&lt;pre&gt;&amp;lt;script type="text/javascript" src="calendar/calendar.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;br&gt;&amp;lt;script type="text/javascript" src="calendar/calendar-setup.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;br&gt;&amp;lt;script type="text/javascript" src="calendar/lang/calendar-en.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;br&gt;&amp;lt;link rel="stylesheet" type="text/css" media="all" href="calendar/skins/aqua/theme.css" /&amp;gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br class="clear"&gt;

&lt;p&gt;Next, I'm going to add a GridView control to display the results of
my search.&lt;/p&gt;

&lt;div class="code"&gt;&lt;pre&gt;&amp;lt;asp:gridview id="gridView" autogeneratecolumns="False"&lt;br&gt;              emptydatatext="Sorry, no matching records were found." runat="server"&amp;gt;&lt;br&gt;    &amp;lt;columns&amp;gt;&lt;br&gt;    &amp;lt;asp:boundfield datafield="ProcessName" headertext="Process" readonly="True"/&amp;gt;&lt;br&gt;    &amp;lt;asp:boundfield datafield="TaskName" headertext="Task" readonly="True"/&amp;gt;&lt;br&gt;    &amp;lt;asp:boundfield datafield="ResponsibleName" headertext="Responsible" readonly="True"/&amp;gt;&lt;br&gt;    &amp;lt;asp:boundfield datafield="TaskStatus" headertext="Status" readonly="True"/&amp;gt;&lt;br&gt;    &amp;lt;asp:boundfield datafield="TaskStartDate" headertext="Start Date"&lt;br&gt;                    htmlencode="False" dataformatstring="{0:d}" readonly="True"/&amp;gt;&lt;br&gt;    &amp;lt;asp:boundfield datafield="TaskDueDate" headertext="Due Date"&lt;br&gt;                    htmlencode="False" dataformatstring="{0:d}" readonly="True"/&amp;gt;&lt;br&gt;    &amp;lt;/columns&amp;gt;&lt;br&gt;&amp;lt;/asp:gridview&amp;gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br class="clear"&gt;

&lt;p&gt;With the controls in place, it's time to start adding some code. The first thing I'm going to do is build a DateColumnDecorator class that implements the &lt;strong&gt;IDateColumn&lt;/strong&gt; interface.&lt;/p&gt;

&lt;div class="code"&gt;&lt;pre&gt;&lt;span class="keyword"&gt;using&lt;/span&gt; System;&lt;br&gt;&lt;span class="keyword"&gt;using&lt;/span&gt; Teamplate.BLL.Data;&lt;br&gt;
&lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;class&lt;/span&gt; DateColumnDecorator : IDateColumn&lt;br&gt;{&lt;br&gt;    &lt;span class="keyword"&gt;private&lt;/span&gt; &lt;span class="keyword"&gt;readonly&lt;/span&gt; &lt;span class="keyword"&gt;string&lt;/span&gt; displayName;&lt;br&gt;    &lt;span class="keyword"&gt;private&lt;/span&gt; &lt;span class="keyword"&gt;readonly&lt;/span&gt; IDateColumn column;&lt;br&gt;
    &lt;span class="keyword"&gt;public&lt;/span&gt; DateColumnDecorator(&lt;span class="keyword"&gt;string&lt;/span&gt; displayName, IDateColumn column)&lt;br&gt;    {&lt;br&gt;        &lt;span class="keyword"&gt;this&lt;/span&gt;.displayName = displayName;&lt;br&gt;        &lt;span class="keyword"&gt;this&lt;/span&gt;.column = column;&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    &lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;override&lt;/span&gt; &lt;span class="keyword"&gt;string&lt;/span&gt; ToString()&lt;br&gt;    {&lt;br&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt; displayName;&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    &lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;string&lt;/span&gt; ColumnName&lt;br&gt;    {&lt;br&gt;        &lt;span class="keyword"&gt;get&lt;/span&gt; { &lt;span class="keyword"&gt;return&lt;/span&gt; column.ColumnName; }&lt;br&gt;    }&lt;br&gt;
    &lt;span class="keyword"&gt;public&lt;/span&gt; ICriteria GreaterThan(DateTime value)&lt;br&gt;    {&lt;br&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt; column.GreaterThan(value);&lt;br&gt;    }&lt;br&gt;
    // more methods
}&lt;/pre&gt;&lt;/div&gt;
&lt;br class="clear"&gt;

&lt;p&gt;The primary purpose of the decorator class is to wrap another &lt;strong&gt;IDateColumn&lt;/strong&gt; instance in order to override the ToString method. By default the ToString method returns the value of the ColumnName property. Although useful, this is not what I want to display to the user in the DropDownList control. All of the other methods on the decorator simply delegate to the &lt;strong&gt;IDateColumn&lt;/strong&gt; instance being wrapped.&lt;br&gt;&lt;/p&gt;

&lt;p&gt;The DateColumnDecorator is put to work in the Columns property as seen below.&lt;/p&gt;

&lt;div class="code"&gt;&lt;pre&gt;&lt;span class="keyword"&gt;private&lt;/span&gt; IList&amp;lt;IDateColumn&amp;gt; columns;&lt;br&gt;&lt;span class="keyword"&gt;private&lt;/span&gt; IList&amp;lt;IDateColumn&amp;gt; Columns&lt;br&gt;{&lt;br&gt;    &lt;span class="keyword"&gt;get&lt;/span&gt;&lt;br&gt;    {&lt;br&gt;        &lt;span class="keyword"&gt;if&lt;/span&gt; (columns == &lt;span class="keyword"&gt;null&lt;/span&gt;)&lt;br&gt;        {&lt;br&gt;            columns = &lt;span class="keyword"&gt;new&lt;/span&gt; List&amp;lt;IDateColumn&amp;gt;();&lt;br&gt;            columns.Add(&lt;span class="keyword"&gt;new&lt;/span&gt; DateColumnDecorator("Due Date", TaskList.TaskDueDate));&lt;br&gt;            columns.Add(&lt;span class="keyword"&gt;new&lt;/span&gt; DateColumnDecorator("Start Date", TaskList.TaskStartDate));&lt;br&gt;        }&lt;br&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt; columns;&lt;br&gt;    }&lt;br&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;br class="clear"&gt;

&lt;p&gt;My second DropDownList control allows the user to select an operator that describes how they want to compare against the selected date. The goal here is to translate several unique method signatures into one general purpose signature. The easiest way I could think of to do this was to introduce a command pattern.&lt;/p&gt;

&lt;p&gt;I'm going to start with the following abstract class whose primary responsibility is to handle the display name functionality.&lt;/p&gt;

&lt;div class="code"&gt;&lt;pre&gt;&lt;span class="keyword"&gt;using&lt;/span&gt; System;&lt;br&gt;&lt;span class="keyword"&gt;using&lt;/span&gt; Teamplate.BLL.Data;&lt;br&gt;&lt;br&gt;&lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;abstract&lt;/span&gt; &lt;span class="keyword"&gt;class&lt;/span&gt; DateCommand&lt;br&gt;{&lt;br&gt;    &lt;span class="keyword"&gt;private&lt;/span&gt; &lt;span class="keyword"&gt;readonly&lt;/span&gt; &lt;span class="keyword"&gt;string&lt;/span&gt; displayName;&lt;br&gt;&lt;br&gt;    &lt;span class="keyword"&gt;public&lt;/span&gt; DateCommand(&lt;span class="keyword"&gt;string&lt;/span&gt; displayName)&lt;br&gt;    {&lt;br&gt;        &lt;span class="keyword"&gt;this&lt;/span&gt;.displayName = displayName;&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    &lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;override&lt;/span&gt; &lt;span class="keyword"&gt;string&lt;/span&gt; ToString()&lt;br&gt;    {&lt;br&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt; displayName;&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    &lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;abstract&lt;/span&gt; ICriteria Execute(IDateColumn column, DateTime value);&lt;br&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;br class="clear"&gt;

&lt;p&gt;For each operator that I want to appear in the DropDownList control, I am going to create a class that inherits from the abstract DateCommand class. Now all I need to do is override the Execute method and call the corresponding method on the &lt;strong&gt;IDateColumn&lt;/strong&gt; instance being passed in to the Execute method.&lt;/p&gt;

&lt;div class="code"&gt;&lt;pre&gt;&lt;span class="keyword"&gt;using&lt;/span&gt; System;&lt;br&gt;&lt;span class="keyword"&gt;using&lt;/span&gt; Teamplate.BLL.Data;&lt;br&gt;&lt;br&gt;&lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;class&lt;/span&gt; GreaterThan : DateCommand&lt;br&gt;{&lt;br&gt;    &lt;span class="keyword"&gt;public&lt;/span&gt; GreaterThan() : base("&amp;gt;")&lt;br&gt;    {&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    &lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;override&lt;/span&gt; ICriteria Execute(IDateColumn column, DateTime value)&lt;br&gt;    {&lt;br&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt; column.GreaterThan(value);&lt;br&gt;    }&lt;br&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;br class="clear"&gt;

&lt;p&gt;This well-known, although often overlooked, technique is called &lt;strong&gt;double-dispatch&lt;/strong&gt;.&lt;/p&gt;

&lt;div class="code"&gt;&lt;pre&gt;&lt;span class="keyword"&gt;using&lt;/span&gt; System;&lt;br&gt;&lt;span class="keyword"&gt;using&lt;/span&gt; Teamplate.BLL.Data;&lt;br&gt;&lt;br&gt;&lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;class&lt;/span&gt; GreaterThanOrEqualTo : DateCommand&lt;br&gt;{&lt;br&gt;    &lt;span class="keyword"&gt;public&lt;/span&gt; GreaterThanOrEqualTo() : base("&amp;gt;=")&lt;br&gt;    {&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    &lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;override&lt;/span&gt; ICriteria Execute(IDateColumn column, DateTime value)&lt;br&gt;    {&lt;br&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt; column.GreaterThanOrEqualTo(value);&lt;br&gt;    }&lt;br&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;br class="clear"&gt;

&lt;p&gt;The command objects adapt each call on a unique method signature of the &lt;strong&gt;IDateColumn&lt;/strong&gt; instance into a general purpose method called Execute. When I add a Commands property to my code behind, all of my command objects are added to a list of type DateCommand. Nothing like a little polymorphism to spice things up.&lt;/p&gt;

&lt;div class="code"&gt;&lt;pre&gt;&lt;span class="keyword"&gt;private&lt;/span&gt; IList&amp;lt;DateCommand&amp;gt; commands;&lt;br&gt;&lt;span class="keyword"&gt;private&lt;/span&gt; IList&amp;lt;DateCommand&amp;gt; Commands&lt;br&gt;{&lt;br&gt;    &lt;span class="keyword"&gt;get&lt;/span&gt;&lt;br&gt;    {&lt;br&gt;        &lt;span class="keyword"&gt;if&lt;/span&gt; (commands == &lt;span class="keyword"&gt;null&lt;/span&gt;)&lt;br&gt;        {&lt;br&gt;            commands = &lt;span class="keyword"&gt;new&lt;/span&gt; List&amp;lt;DateCommand&amp;gt;();&lt;br&gt;            commands.Add(&lt;span class="keyword"&gt;new&lt;/span&gt; GreaterThan());&lt;br&gt;            commands.Add(&lt;span class="keyword"&gt;new&lt;/span&gt; GreaterThanOrEqualTo());&lt;br&gt;            commands.Add(&lt;span class="keyword"&gt;new&lt;/span&gt; EqualTo());&lt;br&gt;            commands.Add(&lt;span class="keyword"&gt;new&lt;/span&gt; LessThanOrEqualTo());&lt;br&gt;            commands.Add(&lt;span class="keyword"&gt;new&lt;/span&gt; LessThan());&lt;br&gt;        }&lt;br&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt; commands;&lt;br&gt;    }&lt;br&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;br class="clear"&gt;

&lt;p&gt;With everything in its place, it's now time to hookup our event handlers, load the DropDownList controls and of course obtain a new session token.&lt;/p&gt;

&lt;div class="code"&gt;&lt;pre&gt;&lt;span class="keyword"&gt;private&lt;/span&gt; &lt;span class="keyword"&gt;string&lt;/span&gt; sessionToken;&lt;br&gt;&lt;span class="keyword"&gt;private&lt;/span&gt; &lt;span class="keyword"&gt;int&lt;/span&gt; userId;&lt;br&gt;&lt;br&gt;&lt;span class="keyword"&gt;protected&lt;/span&gt; &lt;span class="keyword"&gt;void&lt;/span&gt; Page_Load(&lt;span class="keyword"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;br&gt;{&lt;br&gt;    BSession bSession = &lt;span class="keyword"&gt;new&lt;/span&gt; BSession();&lt;br&gt;    bSession.Connect(&lt;span class="keyword"&gt;string&lt;/span&gt;.Empty, &lt;span class="keyword"&gt;string&lt;/span&gt;.Empty, &lt;span class="keyword"&gt;string&lt;/span&gt;.Empty);&lt;br&gt;    sessionToken = bSession.GetToken();&lt;br&gt;    userId = bSession.GetUserId();&lt;br&gt;&lt;br&gt;    LoadControls();&lt;br&gt;    HookupEventHandlers();&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;span class="keyword"&gt;private&lt;/span&gt; &lt;span class="keyword"&gt;void&lt;/span&gt; HookupEventHandlers()&lt;br&gt;{&lt;br&gt;    searchButton.Click += &lt;span class="keyword"&gt;delegate&lt;/span&gt; { FindMatchingTaskRecords(); };&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;span class="keyword"&gt;private&lt;/span&gt; &lt;span class="keyword"&gt;void&lt;/span&gt; LoadControls()&lt;br&gt;{&lt;br&gt;    &lt;span class="keyword"&gt;if&lt;/span&gt; (!IsPostBack)&lt;br&gt;    {&lt;br&gt;        columnsDropDownList.DataSource = Columns;&lt;br&gt;        columnsDropDownList.DataBind();&lt;br&gt;&lt;br&gt;        commandsDropDownList.DataSource = Commands;&lt;br&gt;        commandsDropDownList.DataBind();&lt;br&gt;    }&lt;br&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;br class="clear"&gt;

&lt;p&gt;And finally, it's time to bring the new &lt;strong&gt;BQueryRuntime&lt;/strong&gt; API into play. Pay attention to the SearchCriteria property as that's where all of the magic takes place.&lt;/p&gt;

&lt;div class="code"&gt;&lt;pre&gt;&lt;span class="keyword"&gt;private&lt;/span&gt; ICriteria SearchCriteria&lt;br&gt;{&lt;br&gt;    &lt;span class="keyword"&gt;get&lt;/span&gt;&lt;br&gt;    {&lt;br&gt;        IDateColumn selectedColumn = Columns[columnsDropDownList.SelectedIndex];&lt;br&gt;        DateCommand selectedCommand = Commands[commandsDropDownList.SelectedIndex];&lt;br&gt;&lt;br&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt; selectedCommand.Execute(selectedColumn, DateTime.Parse(date.Text));&lt;br&gt;    }&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;span class="keyword"&gt;private&lt;/span&gt; &lt;span class="keyword"&gt;void&lt;/span&gt; FindMatchingTaskRecords()&lt;br&gt;{&lt;br&gt;    BQueryRuntime runtime = &lt;span class="keyword"&gt;new&lt;/span&gt; BQueryRuntime();&lt;br&gt;    runtime.SetSessionToken(sessionToken);&lt;br&gt;&lt;br&gt;    IQuery query = runtime.CreateQuery(QueryType.TaskList);&lt;br&gt;    query.AddCriteria(&lt;br&gt;        TaskList.TaskStatus.MatchAny(TaskStatus.Ready | TaskStatus.Waiting)&lt;br&gt;            .And(TaskList.ResponsibleId.EqualTo(userId))&lt;br&gt;            .And(SearchCriteria));&lt;br&gt;&lt;br&gt;    gridView.DataSource = runtime.ExecuteDataSet(query);&lt;br&gt;    gridView.DataBind();&lt;br&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;br class="clear"&gt;

&lt;p&gt;That's it. Feel free to download the complete project &lt;em&gt;&lt;a href="/DeveloperProgram/files/23/wf_cpdp_ccdp/entry12539.aspx"&gt;&amp;lt;here/&amp;gt;&lt;/a&gt;&lt;/em&gt;. If you like what you see, or even if you don't, I'm open to comments.&lt;/p&gt;

&lt;img src="http://www.captaris.com/DeveloperProgram/aggbug.aspx?PostID=12540" width="1" height="1"&gt;</content><author><name>DonCampbell</name><uri>http://www.captaris.com/DeveloperProgram/members/DonCampbell.aspx</uri></author></entry><entry><title>Adding Search To Your TaskList</title><link rel="alternate" type="text/html" href="http://www.captaris.com/DeveloperProgram/blogs/doncampbell_blog/archive/2007/05/31/12514.aspx" /><id>http://www.captaris.com/DeveloperProgram/blogs/doncampbell_blog/archive/2007/05/31/12514.aspx</id><published>2007-05-31T18:49:00Z</published><updated>2007-05-31T18:49:00Z</updated><content type="html">&lt;p&gt;Adding search capabilities to a task list should not be a difficult thing to do. To illustrate my point, I am going to describe how to build the following sample application using the new &lt;strong&gt;BQueryRuntime&lt;/strong&gt; API.&lt;/p&gt;

&lt;img alt="Search By Name" src="http://www.teamplate.com/DevProgramImages/SearchByName.jpg"&gt;
&lt;br class="clear"&gt;&lt;br&gt;

&lt;p&gt;After creating a new website in Visual Studio 2005, the first thing I’m going to do is add the following ASP.NET controls to the form tag within my web page.&lt;/p&gt;

&lt;div class="code"&gt;&lt;pre&gt;&amp;lt;div style="margin: 6px 0px;"&amp;gt;&lt;br&gt;    &amp;lt;asp:dropdownlist id="columnsDropDownList" runat="server"/&amp;gt;&lt;br&gt;    &amp;lt;asp:dropdownlist id="formatsDropDownList" runat="server"/&amp;gt;&lt;br&gt;    &amp;lt;asp:textbox id="searchPattern" runat="server"/&amp;gt;&lt;br&gt;    &amp;lt;asp:button id="searchButton" runat="server" text="Search"/&amp;gt;&lt;br&gt;&amp;lt;/div&amp;gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br class="clear"&gt;

&lt;p&gt;These controls make up my search bar. I am going to use the DropDownList controls to display the columns and formats the user selects to match the pattern they enter into the TextBox control. The Button control is used to kick off the search.&lt;/p&gt;
&lt;p&gt;Next, I am going to add a GridView control to display the results of my search. In order to limit which columns are being displayed to the user I need to do two things. The first is adding the "autogeneratecolumns" attribute, set to false, to the gridview tag. The second is adding a BoundField control for each column I want to display to the user.&lt;/p&gt;

&lt;div class="code"&gt;&lt;pre&gt;&amp;lt;asp:gridview id="gridView" autogeneratecolumns="False"&lt;br&gt;              emptydatatext="Sorry, no matching records were found." runat="server"&amp;gt;&lt;br&gt;    &amp;lt;columns&amp;gt;&lt;br&gt;    &amp;lt;asp:boundfield datafield="ProcessName" headertext="Process" readonly="True"/&amp;gt;&lt;br&gt;    &amp;lt;asp:boundfield datafield="TaskName" headertext="Task" readonly="True"/&amp;gt;&lt;br&gt;    &amp;lt;asp:boundfield datafield="ResponsibleName" headertext="Responsible" readonly="True"/&amp;gt;&lt;br&gt;    &amp;lt;asp:boundfield datafield="TaskStatus" headertext="Status" readonly="True"/&amp;gt;&lt;br&gt;    &amp;lt;asp:boundfield datafield="TaskStartDate" headertext="Start Date"&lt;br&gt;                    htmlencode="False" dataformatstring="{0:d}" readonly="True"/&amp;gt;&lt;br&gt;    &amp;lt;asp:boundfield datafield="TaskDueDate" headertext="Due Date"&lt;br&gt;                    htmlencode="False" dataformatstring="{0:d}" readonly="True"/&amp;gt;&lt;br&gt;    &amp;lt;/columns&amp;gt;&lt;br&gt;&amp;lt;/asp:gridview&amp;gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br class="clear"&gt;

&lt;p&gt;Since I like things to look nice, even a sample application, I selected the professional scheme from the auto format option of the GridView control to pretty everything up a bit. You don't need to do this yourself, I just couldn't help myself.&lt;/p&gt;
&lt;p&gt;Now that I have my controls in place, it's time to add some code. The first thing I'm interested in doing is adding the &lt;strong&gt;TaskList.ProcessName&lt;/strong&gt; and the &lt;strong&gt;TaskList.TaskName&lt;/strong&gt; columns to  my first DropDownList control. Both columns implement the &lt;strong&gt;IStringColumn&lt;/strong&gt; interface which in turn represents all of the operations you are able to do with a string column. For this sample the only operation I'm interested in is the &lt;strong&gt;Like()&lt;/strong&gt; method, so I'm going to add an adapter that implements the following interface to my project. The key point to note here is that all column operations return an &lt;strong&gt;ICriteria&lt;/strong&gt; object.&lt;/p&gt;

&lt;div class="code"&gt;&lt;pre&gt;&lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;interface&lt;/span&gt; IStringColumnAdapter&lt;br&gt;{&lt;br&gt;    ICriteria Like(&lt;span class="keyword"&gt;string&lt;/span&gt; pattern);&lt;br&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;br class="clear"&gt;

&lt;p&gt;The code for the adapter is simple enough. The constructor takes a string representing the name to display in the DropDownList and an &lt;strong&gt;IStringColumn&lt;/strong&gt; column representing either the &lt;strong&gt;TaskList.ProcessName&lt;/strong&gt; or &lt;strong&gt;TaskList.TaskName&lt;/strong&gt; column.&lt;/p&gt;

&lt;div class="code"&gt;&lt;pre&gt;&lt;span class="keyword"&gt;using&lt;/span&gt; Teamplate.BLL.Data;&lt;br&gt;&lt;br&gt;&lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;class&lt;/span&gt; StringColumnAdapter : IStringColumnAdapter&lt;br&gt;{&lt;br&gt;    &lt;span class="keyword"&gt;private&lt;/span&gt; &lt;span class="keyword"&gt;readonly&lt;/span&gt; &lt;span class="keyword"&gt;string&lt;/span&gt; displayName;&lt;br&gt;    &lt;span class="keyword"&gt;private&lt;/span&gt; &lt;span class="keyword"&gt;readonly&lt;/span&gt; IStringColumn column;&lt;br&gt;&lt;br&gt;    &lt;span class="keyword"&gt;public&lt;/span&gt; StringColumnAdapter(&lt;span class="keyword"&gt;string&lt;/span&gt; displayName, IStringColumn column)&lt;br&gt;    {&lt;br&gt;        &lt;span class="keyword"&gt;this&lt;/span&gt;.displayName = displayName;&lt;br&gt;        &lt;span class="keyword"&gt;this&lt;/span&gt;.column = column;&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    &lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;override&lt;/span&gt; &lt;span class="keyword"&gt;string&lt;/span&gt; ToString()&lt;br&gt;    {&lt;br&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt; displayName;&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    &lt;span class="keyword"&gt;public&lt;/span&gt; ICriteria Like(&lt;span class="keyword"&gt;string&lt;/span&gt; pattern)&lt;br&gt;    {&lt;br&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt; column.Like(pattern);&lt;br&gt;    }&lt;br&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;br class="clear"&gt;

&lt;p&gt;Next, I'm going to add a Columns property to the code behind of my web page whose only responsibility is to build and return a list of IStringColumnAdapter(s). I've decided to use the lazy load pattern here to insure the columns member variable only gets built once.&lt;/p&gt;

&lt;div class="code"&gt;&lt;pre&gt;&lt;span class="keyword"&gt;private&lt;/span&gt; IList&amp;lt;IStringColumnAdapter&amp;gt; columns;&lt;br&gt;&lt;span class="keyword"&gt;private&lt;/span&gt; IList&amp;lt;IStringColumnAdapter&amp;gt; Columns&lt;br&gt;{&lt;br&gt;    &lt;span class="keyword"&gt;get&lt;/span&gt;&lt;br&gt;    {&lt;br&gt;        &lt;span class="keyword"&gt;if&lt;/span&gt; (columns == &lt;span class="keyword"&gt;null&lt;/span&gt;)&lt;br&gt;        {&lt;br&gt;            columns = &lt;span class="keyword"&gt;new&lt;/span&gt; List&amp;lt;IStringColumnAdapter&amp;gt;();&lt;br&gt;            columns.Add(&lt;span class="keyword"&gt;new&lt;/span&gt; StringColumnAdapter("Process", TaskList.ProcessName));&lt;br&gt;            columns.Add(&lt;span class="keyword"&gt;new&lt;/span&gt; StringColumnAdapter("Task", TaskList.TaskName));&lt;br&gt;        }&lt;br&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt; columns;&lt;br&gt;    }&lt;br&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;br class="clear"&gt;

&lt;p&gt;Now let's turn our attention towards the second DropDownList control. It's purpose is to allow the user to define how the pattern in the TextBox control should be interpreted. Remember we will be calling the &lt;strong&gt;Like()&lt;/strong&gt;  method on the selected string column. The &lt;strong&gt;Like()&lt;/strong&gt; method accepts a pattern that is used to find a match. If you only know the first part of the name you want to search for, you can append a percent sign (%) to your pattern. This would in turn cause the &lt;strong&gt;Like()&lt;/strong&gt; method to  match all names that start with your pattern. Since this is not intuitive to the average user, I have decided to hide the details in the second DropDownList control. Let's continue by adding the following interface to the project.&lt;/p&gt;

&lt;div class="code"&gt;&lt;pre&gt;&lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;interface&lt;/span&gt; IFormatter&lt;br&gt;{&lt;br&gt;    &lt;span class="keyword"&gt;string&lt;/span&gt; Format(&lt;span class="keyword"&gt;params&lt;/span&gt; &lt;span class="keyword"&gt;object&lt;/span&gt;[] args);&lt;br&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;br class="clear"&gt;

&lt;p&gt;The Formatter class itself is easy to build. Again the constructor takes a string representing the name to display in the DropDownList and a second string that represents how we should format the pattern.&lt;/p&gt;

&lt;div class="code"&gt;&lt;pre&gt;&lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;class&lt;/span&gt; Formatter : IFormatter&lt;br&gt;{&lt;br&gt;    &lt;span class="keyword"&gt;private&lt;/span&gt; &lt;span class="keyword"&gt;readonly&lt;/span&gt; &lt;span class="keyword"&gt;string&lt;/span&gt; displayName;&lt;br&gt;    &lt;span class="keyword"&gt;private&lt;/span&gt; &lt;span class="keyword"&gt;readonly&lt;/span&gt; &lt;span class="keyword"&gt;string&lt;/span&gt; format;&lt;br&gt;&lt;br&gt;    &lt;span class="keyword"&gt;public&lt;/span&gt; Formatter(&lt;span class="keyword"&gt;string&lt;/span&gt; displayName, &lt;span class="keyword"&gt;string&lt;/span&gt; format)&lt;br&gt;    {&lt;br&gt;        &lt;span class="keyword"&gt;this&lt;/span&gt;.displayName = displayName;&lt;br&gt;        &lt;span class="keyword"&gt;this&lt;/span&gt;.format = format;&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    &lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;override&lt;/span&gt; &lt;span class="keyword"&gt;string&lt;/span&gt; ToString()&lt;br&gt;    {&lt;br&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt; displayName;&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    &lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;string&lt;/span&gt; Format(&lt;span class="keyword"&gt;params&lt;/span&gt; &lt;span class="keyword"&gt;object&lt;/span&gt;[] args)&lt;br&gt;    {&lt;br&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="keyword"&gt;string&lt;/span&gt;.Format(format, args);&lt;br&gt;    }&lt;br&gt;}&lt;pre&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br class="clear"&gt;

&lt;p&gt;Next we add the Formats property to the code behind of the web page. Note how we have essentially replaced the hard to remember format strings with user friendly text strings.&lt;/p&gt;

&lt;div class="code"&gt;&lt;pre&gt;&lt;span class="keyword"&gt;private&lt;/span&gt; IList&amp;lt;IFormatter&amp;gt; formats;&lt;br&gt;&lt;span class="keyword"&gt;private&lt;/span&gt; IList&amp;lt;IFormatter&amp;gt; Formats&lt;br&gt;{&lt;br&gt;    &lt;span class="keyword"&gt;get&lt;/span&gt;
    {
        &lt;span class="keyword"&gt;if&lt;/span&gt; (formats == &lt;span class="keyword"&gt;null&lt;/span&gt;)&lt;br&gt;        {&lt;br&gt;            formats = &lt;span class="keyword"&gt;new&lt;/span&gt; List&amp;lt;IFormatter&amp;gt;();&lt;br&gt;            formats.Add(&lt;span class="keyword"&gt;new&lt;/span&gt; Formatter("Starts with", "{0}%"));&lt;br&gt;            formats.Add(&lt;span class="keyword"&gt;new&lt;/span&gt; Formatter("Contains", "%{0}%"));&lt;br&gt;            formats.Add(&lt;span class="keyword"&gt;new&lt;/span&gt; Formatter("Ends with", "%{0}"));&lt;br&gt;        }&lt;br&gt;        &lt;span class="keyword"&gt;return&lt;/span&gt; formats;&lt;br&gt;    }&lt;br&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;br class="clear"&gt;

&lt;p&gt;It's now time to hookup our event handlers, load the DropDownList controls and of course obtain a new session token.&lt;/p&gt;

&lt;div class="code"&gt;&lt;pre&gt;&lt;span class="keyword"&gt;private&lt;/span&gt; &lt;span class="keyword"&gt;string&lt;/span&gt; sessionToken;&lt;br&gt;&lt;span class="keyword"&gt;private&lt;/span&gt; &lt;span class="keyword"&gt;int&lt;/span&gt; userId;&lt;br&gt;&lt;br&gt;&lt;span class="keyword"&gt;protected&lt;/span&gt; &lt;span class="keyword"&gt;void&lt;/span&gt; Page_Load(&lt;span class="keyword"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;br&gt;{&lt;br&gt;    BSession bSession = &lt;span class="keyword"&gt;new&lt;/span&gt; BSession();&lt;br&gt;    bSession.Connect(&lt;span class="keyword"&gt;string.&lt;/span&gt;Empty, &lt;span class="keyword"&gt;string&lt;/span&gt;.Empty, &lt;span class="keyword"&gt;string&lt;/span&gt;.Empty);&lt;br&gt;    sessionToken = bSession.GetToken();&lt;br&gt;    userId = bSession.GetUserId();&lt;br&gt;&lt;br&gt;    LoadControls();&lt;br&gt;    HookupEventHandlers();&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;span class="keyword"&gt;private&lt;/span&gt; &lt;span class="keyword"&gt;void&lt;/span&gt; HookupEventHandlers()&lt;br&gt;{&lt;br&gt;    searchButton.Click += &lt;span class="keyword"&gt;delegate&lt;/span&gt; { FindMatchingTaskRecords(); };&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;span class="keyword"&gt;private&lt;/span&gt; &lt;span class="keyword"&gt;void&lt;/span&gt; LoadControls()&lt;br&gt;{&lt;br&gt;    &lt;span class="keyword"&gt;if&lt;/span&gt; (!IsPostBack)&lt;br&gt;    {&lt;br&gt;        columnsDropDownList.DataSource = Columns;&lt;br&gt;        columnsDropDownList.DataBind();&lt;br&gt;&lt;br&gt;        formatsDropDownList.DataSource = Formats;&lt;br&gt;        formatsDropDownList.DataBind();&lt;br&gt;    }&lt;br&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;br class="clear"&gt;

&lt;p&gt;Finally, it's time to add our search method. This is where all the magic happens. FindMatchingTaskRecords is called when the user clicks on the Button control. All we need to do here is ask the &lt;strong&gt;BQueryRuntime&lt;/strong&gt; for a new query object that we populate with shiny new criteria objects. I've decided to limit my result set to only those records that have a &lt;em&gt;Ready&lt;/em&gt; or &lt;em&gt;Waiting&lt;/em&gt; status for which I'm responsible for. The search criteria selected by the user is handled by the SearchCriteria property. Simply format the search pattern using the Formatter selected by the user and then pass it to the selected StringColumnAdapter to generate a new &lt;strong&gt;ICriteria&lt;/strong&gt; object. Add the generated &lt;strong&gt;ICriteria&lt;/strong&gt; object to the query and then pass it off to the &lt;strong&gt;BQueryRuntime&lt;/strong&gt; to be executed. Lastly, bind the DataSet to the GridView control and we are done.&lt;/p&gt;

&lt;div class="code"&gt;&lt;pre&gt;&lt;span class="keyword"&gt;private&lt;/span&gt; ICriteria SearchCriteria&lt;br&gt;{&lt;br&gt;    &lt;span class="keyword"&gt;get&lt;/span&gt;
    {
        IStringColumnAdapter selectedColumn = Columns[columnsDropDownList.SelectedIndex];
        IFormatter selectedFormat = Formats[formatsDropDownList.SelectedIndex];

        &lt;span class="keyword"&gt;return&lt;/span&gt; selectedColumn.Like(selectedFormat.Format(searchPattern.Text));&lt;br&gt;    }&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;span class="keyword"&gt;private&lt;/span&gt; &lt;span class="keyword"&gt;void&lt;/span&gt; FindMatchingTaskRecords()&lt;br&gt;{&lt;br&gt;    BQueryRuntime runtime = &lt;span class="keyword"&gt;new&lt;/span&gt; BQueryRuntime();&lt;br&gt;    runtime.SetSessionToken(sessionToken);&lt;br&gt;&lt;br&gt;    IQuery query = runtime.CreateQuery(QueryType.TaskList);&lt;br&gt;    query.AddCriteria(&lt;br&gt;        TaskList.TaskStatus.MatchAny(TaskStatus.Ready | TaskStatus.Waiting)&lt;br&gt;            .And(TaskList.ResponsibleId.EqualTo(userId))&lt;br&gt;            .And(SearchCriteria));&lt;br&gt;&lt;br&gt;    gridView.DataSource = runtime.ExecuteDataSet(query);&lt;br&gt;    gridView.DataBind();&lt;br&gt;}&lt;br&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;br class="clear"&gt;

&lt;p&gt;That's it. Feel free to download the complete project &lt;a href="/DeveloperProgram/files/23/wf_cpdp_ccdp/entry12513.aspx" target="_blank"&gt;[ here ]&lt;/a&gt;, or if you prefer, you can download a Windows version of the project &lt;a href="/DeveloperProgram/files/23/wf_cpdp_ccdp/entry12512.aspx" target="_blank"&gt;[ here ]&lt;/a&gt;. If you like what you see, or even if you don't, I'm open to comments.&lt;/p&gt;

&lt;img src="http://www.captaris.com/DeveloperProgram/aggbug.aspx?PostID=12514" width="1" height="1"&gt;</content><author><name>DonCampbell</name><uri>http://www.captaris.com/DeveloperProgram/members/DonCampbell.aspx</uri></author></entry><entry><title>Building A Simple TaskList</title><link rel="alternate" type="text/html" href="http://www.captaris.com/DeveloperProgram/blogs/doncampbell_blog/archive/2007/05/22/12467.aspx" /><id>http://www.captaris.com/DeveloperProgram/blogs/doncampbell_blog/archive/2007/05/22/12467.aspx</id><published>2007-05-22T16:39:00Z</published><updated>2007-05-22T16:39:00Z</updated><content type="html">Until recently, building a customized task list involved having an intimate knowledge with our database schema. The &lt;b&gt;BQueryRuntime&lt;/b&gt; API, new to Captaris Workflow 6.5, was designed to change all that by introducing a simple model that would allow you to develop a query without the need to poke around in our database tables.&lt;br&gt;&lt;br&gt;The &lt;b&gt;BQueryRuntime&lt;/b&gt; class has only two responsibilities. The first is to create and return a query object and the second is to execute a query object and return the results in a DataSet. Both operations can be seen in the following sample:

&lt;pre&gt;&lt;div&gt;
&lt;span class="keyword"&gt;using&lt;/span&gt; System;&lt;br&gt;&lt;span class="keyword"&gt;using&lt;/span&gt; System.Data;&lt;br&gt;&lt;span class="keyword"&gt;using&lt;/span&gt; System.Web.UI;&lt;br&gt;&lt;span class="keyword"&gt;using&lt;/span&gt; Teamplate.BLL;&lt;br&gt;&lt;span class="keyword"&gt;using&lt;/span&gt; Teamplate.BLL.Data;&lt;br&gt;&lt;br&gt;&lt;span class="keyword"&gt;namespace&lt;/span&gt; SimpleTaskList&lt;br&gt;{&lt;br&gt;    &lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;partial&lt;/span&gt; &lt;span class="keyword"&gt;class&lt;/span&gt; _Default : Page&lt;br&gt;    {&lt;br&gt;        &lt;span class="keyword"&gt;protected&lt;/span&gt; &lt;span class="keyword"&gt;void&lt;/span&gt; Page_Load(&lt;span class="keyword"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;br&gt;        {&lt;br&gt;            BSession bSession = &lt;span class="keyword"&gt;new&lt;/span&gt; BSession();&lt;br&gt;            bSession.Connect(&lt;span class="keyword"&gt;string&lt;/span&gt;.Empty, &lt;span class="keyword"&gt;string&lt;/span&gt;.Empty, &lt;span class="keyword"&gt;string&lt;/span&gt;.Empty);&lt;br&gt;&lt;br&gt;            gridView.DataSource = SelectAllTasks(bSession.GetToken());&lt;br&gt;            gridView.DataBind();&lt;br&gt;        }&lt;br&gt;&lt;br&gt;        &lt;span class="keyword"&gt;private&lt;/span&gt; DataSet SelectAllTasks(&lt;span class="keyword"&gt;string&lt;/span&gt; sessionToken)&lt;br&gt;        {&lt;br&gt;            BQueryRuntime runtime = &lt;span class="keyword"&gt;new&lt;/span&gt; BQueryRuntime();&lt;br&gt;            runtime.SetSessionToken(sessionToken);&lt;br&gt;&lt;br&gt;            &lt;span class="highlight"&gt;IQuery query = runtime.CreateQuery(QueryType.TaskList);&lt;/span&gt;
            &lt;span class="highlight"&gt;&lt;span class="keyword"&gt;return&lt;/span&gt; runtime.ExecuteDataSet(query);&lt;/span&gt;
        }
    }
}
&lt;/div&gt;&lt;/pre&gt;&lt;br&gt;

The above sample is useful if you only have a few task records in your database. Since this is generally not the case, you need a way to limit the result set to only those records you are interested in. This is done by adding criteria to the query object. Criteria objects are created using the following syntax:&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;i&gt;ColumnName.Operator(valueToCompare)&lt;/i&gt;&lt;br&gt;&lt;br&gt;The task list columns themselves are made available via the &lt;b&gt;TaskList&lt;/b&gt; column collection object as seen in the following example:

&lt;pre&gt;&lt;div&gt;
&lt;span class="keyword"&gt;using&lt;/span&gt; System;&lt;br&gt;&lt;span class="keyword"&gt;using&lt;/span&gt; System.Data;&lt;br&gt;&lt;span class="keyword"&gt;using&lt;/span&gt; System.Web.UI;&lt;br&gt;&lt;span class="keyword"&gt;using&lt;/span&gt; Teamplate.BLL;&lt;br&gt;&lt;span class="keyword"&gt;using&lt;/span&gt; Teamplate.BLL.Data;&lt;br&gt;&lt;br&gt;&lt;span class="keyword"&gt;namespace&lt;/span&gt; SimpleTaskList&lt;br&gt;{&lt;br&gt;    &lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="keyword"&gt;partial&lt;/span&gt; &lt;span class="keyword"&gt;class&lt;/span&gt; _Default : Page&lt;br&gt;    {&lt;br&gt;        &lt;span class="keyword"&gt;protected&lt;/span&gt; &lt;span class="keyword"&gt;void&lt;/span&gt; Page_Load(&lt;span class="keyword"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;br&gt;        {&lt;br&gt;            BSession bSession = &lt;span class="keyword"&gt;new&lt;/span&gt; BSession();&lt;br&gt;            bSession.Connect(&lt;span class="keyword"&gt;string&lt;/span&gt;.Empty, &lt;span class="keyword"&gt;string&lt;/span&gt;.Empty, &lt;span class="keyword"&gt;string&lt;/span&gt;.Empty);&lt;br&gt;&lt;br&gt;            gridView.DataSource = SelectAllTasksFor(bSession.GetUserId(), bSession.GetToken());&lt;br&gt;            gridView.DataBind();&lt;br&gt;        }&lt;br&gt;&lt;br&gt;        &lt;span class="keyword"&gt;private&lt;/span&gt; DataSet SelectAllTasksFor(&lt;span class="keyword"&gt;int&lt;/span&gt; userId, &lt;span class="keyword"&gt;string&lt;/span&gt; sessionToken)&lt;br&gt;        {&lt;br&gt;            BQueryRuntime runtime = &lt;span class="keyword"&gt;new&lt;/span&gt; BQueryRuntime();&lt;br&gt;            runtime.SetSessionToken(sessionToken);&lt;br&gt;&lt;br&gt;            IQuery query = runtime.CreateQuery(QueryType.TaskList);&lt;br&gt;            &lt;span class="highlight"&gt;query.AddCriteria(TaskList.TaskStatus.MatchAny(TaskStatus.Ready | TaskStatus.Waiting));&lt;/span&gt;
            &lt;span class="highlight"&gt;query.AddCriteria(TaskList.ResponsibleId.EqualTo(userId));&lt;/span&gt;

            &lt;span class="keyword"&gt;return&lt;/span&gt; runtime.ExecuteDataSet(query);&lt;br&gt;        }&lt;br&gt;    }&lt;br&gt;}&lt;br&gt;
&lt;/div&gt;&lt;/pre&gt;

That's it. Simply ask the &lt;b&gt;BQueryRuntime&lt;/b&gt; to create a query object, add some criteria objects to limit the result set, and then ask the &lt;b&gt;BQueryRuntime&lt;/b&gt; to execute your query object and return you a nice new DataSet.&lt;br&gt;&lt;img src="http://www.captaris.com/DeveloperProgram/aggbug.aspx?PostID=12467" width="1" height="1"&gt;</content><author><name>DonCampbell</name><uri>http://www.captaris.com/DeveloperProgram/members/DonCampbell.aspx</uri></author></entry></feed>