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 !