As we have said (part 1), we are ready to write code for the class UserControls_ListBoxesFT_C. Well! Inside the class we will use variables named according to the properties of the class. For example, the _WidthLB variable corresponds to the C_WidthLB property, _DT_In - to C_DT_In, etc. All properties are simple enough and are written like that:

.............

public int C_SortBy

{

get { return _SortBy; }

set { _SortBy = value; }

}

public int C_WidthLB

{

get { return _WidthLB; }

set { _WidthLB = value; }

}

.............

etc.

Some difference have the C_DataIn and C_DataOut properties:

public DataTable C_DataIn

{

set

{

_DT_In = dataTable_Sort ( value);

//Clones the structure of the _DT_In DataTable

_DT_Out = _DT_In.Clone();

//here you can set default value for the _DT_Out

}

}

public DataTable C_DataOut

{

get{return _DT_Out;}

}

As you can see, first of all we set _DT_In as sorted value (with the help of the method dataTable_Sort) and then set _DT_Out as the cloned structure of the _DT_In. The method dataTable_Sort receives some DataTable and returns the sorted table(according to the _SortBy variable) :

private DataTable dataTable_Sort(DataTable dt)

{

DataView dv;

DataTable dtHelp;

DataRow dr;

int iCount = 0;

int iMax = dt.Rows.Count;

dtHelp = dt.Copy();

dv = dtHelp.DefaultView;

dv.Sort = dt.Columns[_SortBy].Caption ;

dt.Clear();

for (iCount = 0; iCount < iMax; iCount++)

{

dr = dt.NewRow();

dr[0]= dv[iCount][0];

dr[1] = dv[iCount][1];

dt.Rows.Add(dr);

}

return dt;

}

Pay attention that the C_SortBy property has to be set before the C_DataIn property.

In order to bind the ListBox control we use the buildListBox method:

private void buildListBox(ListBox lb,DataTable dt)

{

lb.DataTextField = dt.Columns[1].Caption;

lb.DataValueField = dt.Columns[0].Caption;

lb.DataSource = dt;

lb.DataBind();

}

On "Load" event we bind our ListBox controls:

if (!IsPostBack)

{

buildListBox(ListBoxFrom, _DT_In);

buildListBox(ListBoxTo, _DT_Out);

}

On "PreRender" event we "rebuild" our control according to set values:

if (IsPostBack)

{ return; }

ListBoxFrom.Width = Unit.Pixel(_WidthLB);

ListBoxFrom.Height = Unit.Pixel(_HeightLB);

ListBoxTo.Width = Unit.Pixel(_WidthLB);

ListBoxTo.Height = Unit.Pixel(_HeightLB);

ButtonFrom.Text = _LabelFrom;

ButtonTo.Text = _LabelTo ;

ButtonHTMLFrom.Value = _LabelFrom;

ButtonHTMLTo.Value = _LabelTo;

ButtonFrom.Visible = false;

ButtonTo.Visible = false;

ButtonHTMLFrom.Visible = false;

ButtonHTMLTo.Visible = false;

if (_Client)

{

ButtonHTMLFrom.Visible = true;

ButtonHTMLTo.Visible = true;

}

else

{

ButtonFrom.Visible = true;

ButtonTo.Visible = true;

}

On "Button_Click" events (server controls, not HTML) we should add the selected item to _DT_To and delete this item from _DT_Out (or vice versa, it is depends on the event) and then bind the ListBox controls. We do that with the help of the onClickFromTo method :

private void onClickFromTo(bool clickFrom)

{

ListBox lb;

DataTable dtFrom;

DataTable dtTo;

int iItemsList = 0;

int iCount = 0;

int iCountHelp = 0;

if (clickFrom)

{

lb = ListBoxFrom;

dtFrom = _DT_In;

dtTo = _DT_Out;

}

else

{

lb = ListBoxTo;

dtFrom = _DT_Out;

dtTo = _DT_In;

}

iItemsList = lb.Items.Count;

for (iCount = 0; iCount < iItemsList; iCount++)

{

if (lb.Items[iCount].Selected)

{

DataRow dr;

dr = dtTo.NewRow();

dr[0] = dtFrom.Rows[iCount - iCountHelp][0];

dr[1] = dtFrom.Rows[iCount - iCountHelp][1];

dtTo.Rows.Add(dr);

dtFrom.Rows[iCount - iCountHelp].Delete();

iCountHelp = iCountHelp + 1;

}

}

if (clickFrom)

{

_DT_In = dataTable_Sort( dtFrom.Copy());

_DT_Out = dataTable_Sort ( dtTo.Copy());

}

else

{

_DT_Out = dataTable_Sort( dtFrom.Copy());

_DT_In = dataTable_Sort( dtTo.Copy());

}

buildListBox(ListBoxFrom,_DT_In );

buildListBox(ListBoxTo,_DT_Out );

}

In order to save the control view-state changes after the last postback and restore the view-state information we use SaveViewState and LoadViewState methods:

protected override object SaveViewState()

{

object VS_base = base.SaveViewState();

object[] VS_all = new object[10];

VS_all[0] = VS_base;

VS_all[1] = _DT_In;

VS_all[2] = _DT_Out;

VS_all[3] = _Client;

VS_all[4] = _SortBy;

VS_all[5] = _WidthLB;

VS_all[6] = _HeightLB;

VS_all[7] = _LabelFrom;

VS_all[8] = _LabelTo;

VS_all[9] = _SortByText;

return VS_all;

}

protected override void LoadViewState(object VS_saved)

{

if (VS_saved != null)

{

object[] VS_all = (object[])VS_saved;

if (VS_all[0] != null)

{

base.LoadViewState(VS_all[0]);

}

if (VS_all[1] != null)

{

_DT_In = (DataTable)VS_all[1];

}

if (VS_all[2] != null)

{

_DT_Out = (DataTable)VS_all[2];

}

if (VS_all[3] != null)

{

_Client = (bool)VS_all[3];

}

if (VS_all[4] != null)

{

_SortBy = (int)VS_all[4];

}

if (VS_all[5] != null)

{

_WidthLB = (int)VS_all[5];

}

if (VS_all[6] != null)

{

_HeightLB = (int)VS_all[6];

}

if (VS_all[7] != null)

{

_LabelFrom = (string)VS_all[7];

}

if (VS_all[8] != null)

{

_LabelTo = (string)VS_all[8];

}

if (VS_all[9] != null)

{

_SortByText = (bool)VS_all[9];

}

}

}

OK! Our control is ready to work if the C_Client property set to "false", this is : with using "PostBack" for every "data exchange" between ListBoxes. Now we should force to work the control "on client" (C_Client = true). As usually, let's drink a cup of coffee before we shall pass to the third part .

Good luck in programming !