ARTICLE

Building the ListBoxesFT_C ASP.NET Web User Control in Visual Studio 2005: Part II

Posted by Michael Livshitz Articles | Visual Studio 2010 November 09, 2006
In multi-part article, I share how you can build your own ASP.NET web user control.
Reader Level:

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 !

Login to add your contents and source code to this article
post comment
     

Dear July!

When you write code for some Web user control you should pay attention to the SaveViewState() and LoadViewState() methods (may be this is the reason of your problem ?!). You have to use these methods to save any objects (DataTable, width , etc.) that you need , when the PostBack event occurs (this is : clicking some Button control , etc.). See, for example , the second part of my article. Example of the code for client-side process you will be able to see in the third part of the article. The full text (code )  and using of the control on an Web Form will be published  in few days (part 4 and part 5).

Thank you very much and good luck in programming!

Michael.

Posted by Michael Livshitz Nov 10, 2006

Hello Michael:

I have a problem with user controls that I made.

For example, I have a user control with txtName, txtDescription and add button. When I use this controls, and load the product information in textboxs(txtName and txtDescription), I write:

ctrProduct.IdProduct = 4; For example

In the page load, I write:

DataView dvproduct= getproduct(idProduct);

txtName.Text = dvproduct.Table.Rows[0]["name"];

This work fine!. But when I click on add button, the IdProduct property is lost. And when I Add this product, i dont have idProduct.

ths same occurs when I click on button >> the listbox, in the event onClickFrom, The DataIn is lost.

could you help me, please?

 

Thanks!!!

Posted by July Marcela Moreno Gomez Nov 09, 2006
COMMENT USING
PREMIUM SPONSORS
DynamicPDF™ product line allows you to dynamically generate PDF documents, merge PDF documents and add new content to existing PDF documents from within your applications.
Join a Chapter
SPONSORED BY
  • PDF reports have never been easier to create. With our included WYSIWYG Designer, you can layout your reports, set up your data source and let DynamicPDF ReportWriter do the rest.
Get Career Advice from Experts