Hello everybody and thanks in advance,
I´ve read several threads about but I'm very confused. The thing is I'm dynamically creating some textboxes inside a panel control which is placed inside a formview whith this code...
protected void Muestra_Precio_Stock_BT_Click(object sender, EventArgs e)
{
CheckBoxList FormatosCL = (CheckBoxList)FormViewDiscos.FindControl("FormatosCL");
Panel Precio_Stock_PN = (Panel)FormViewDiscos.FindControl("CB_Precio_Stock_PN");
Label NuevoPrecioLB = null;
TextBox NuevoPrecioTB = null;
Label NuevoStockLB = null;
TextBox NuevoStockTB = null;
foreach (ListItem item in FormatosCL.Items)
{
if(item.Selected)
{
NuevoPrecioLB = new Label();
NuevoPrecioTB = new TextBox();
NuevoStockLB = new Label();
NuevoStockTB = new TextBox();
NuevoPrecioLB.ID = "NuevoPrecioLB_" + FormatosCL.Items.IndexOf(item);
NuevoPrecioLB.Text = "PRECIO " + item.Text + ": ";
NuevoPrecioTB.ID = "NuevoPrecioTB_" + FormatosCL.Items.IndexOf(item);
NuevoStockLB.ID = "NuevoStockLB_" + FormatosCL.Items.IndexOf(item);
NuevoStockLB.Text = " STOCK " + item.Text + ": ";
NuevoStockTB.ID = "NuevoStockTB_" + FormatosCL.Items.IndexOf(item);
Precio_Stock_PN.Controls.Add(NuevoPrecioLB);
Precio_Stock_PN.Controls.Add(NuevoPrecioTB);
Precio_Stock_PN.Controls.Add(NuevoStockLB);
Precio_Stock_PN.Controls.Add(NuevoStockTB);
Precio_Stock_PN.Controls.Add(new LiteralControl("<br />"));
}
}
}
Well, this works well, when I run the project the textboxes and labels are created as expected, I can see them and write into the textboxes. I`ve put the same code into Page_Load event and now I can get the created controls and avoid the nullpointerexception (that was my first problem) when I click the INSERT button of the formview. The problem is that, in the following code...
protected void InsertButton_Click(object sender, EventArgs e)
{
TextBox DiscIdTB = (TextBox)FormViewDiscos.FindControl("DiscIdTB");
TextBox CaratulaTB = (TextBox)FormViewDiscos.FindControl("CaratulaTB");
CheckBoxList CancionesCL = (CheckBoxList)FormViewDiscos.FindControl("CancionesCL");
CheckBoxList FormatosCL = (CheckBoxList)FormViewDiscos.FindControl("FormatosCL");
using (SqlConnection conexion = new SqlConnection(ConfigurationManager.ConnectionStrings["ConexionBBDD-Discos"].ConnectionString))
{
conexion.Open();
cmd.Connection = conexion;
cmd.CommandText = "INSERT INTO DISCOS_FORMATOS (ID_DISCO, ID_FORMATO, PRECIO, STOCK) VALUES ((SELECT MAX(ID_DISCO) FROM DISCOS), #IdFormato, 0, 0)";
foreach (ListItem item in FormatosCL.Items)
{
if (item.Selected)
{
Panel Precio_Stock_PN = (Panel)FormViewDiscos.FindControl("CB_Precio_Stock_PN");
string control = "NuevoPrecioTB_" + (FormatosCL.Items.IndexOf(item));
string control2 = "NuevoStockTB_" + (FormatosCL.Items.IndexOf(item));
TextBox Precio = (TextBox)Precio_Stock_PN.FindControl(control);
TextBox Stock = (TextBox)Precio_Stock_PN.FindControl(control2);
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("#IdFormato", item.Value);
cmd.Parameters.AddWithValue("#IdPrecio", Convert.ToInt32(Precio.Text));
cmd.Parameters.AddWithValue("#IdStock", Convert.ToInt32(Stock.Text));
cmd.ExecuteNonQuery();
}
}
conexion.Close();
cmd.Dispose();
}
}
when the execution reaches these lines, dynamically created textboxes lost their values, returning always 0...
cmd.Parameters.AddWithValue("#IdPrecio", Convert.ToInt32(Precio.Text));
cmd.Parameters.AddWithValue("#IdStock", Convert.ToInt32(Stock.Text));
How can I preserve their user typed values?
Have you tried putting the code in the Page_Load method inside a block with
if (!IsPostBack)
{
//
}
Another thing you can try if this doesn't work is saving the typed-in values in Session variables.
I don't think the InsertButton is important here. By the way, if you use the runat=server on the objects you don't have to use FindControl, the server will be able to manage it. Also for dynamic controls you might want to try a different approach like: GridView (remove headers and it won't look like a grid), a DataList, or a ListView. What goes inside the ItemTemplate are the objects you are repeating/creating dynamically. You can add labels and textboxes here. For example:
<asp:ListView ID="repeatedStuff" runat="server"><ItemTemplate>
</ItemTemplate>
</asp:ListView>
Or
<asp:DataListID="list"
CellPadding="2"
RepeatDirection="Vertical"
RepeatLayout="Table"
RepeatColumns="2"
runat="server">
<ItemTemplate>
<asp:CheckBoxID="cboxP"AutoPostBack="True"runat="server"/>
<asp:Labelrunat="server"Text='<%#Bind("Nombre")%>'ID='<%#Bind("ID")%>'></asp:Label>
</ItemTemplate>
</asp:DataList>
What remains after this approach is managing the binding and how to identify them when an event is triggered. Like adding a textchange event on server side, if you bind the ID value on the event you ask for the sender's ID and then you can know which one is being "textchanged".
Related
I have a Table dynamically generated and inside of 2 columns there are TextBoxes. During the postback the Textboxes are always empty even if I fill them.
The table is builted in this way:
protected void ddlScalaTaglie_SelectedIndexChanged(object sender, EventArgs e)
{
DataTable dtRighe = oTab.getScaleTaglieRighe(ddlScalaTaglie.SelectedValue);
//dt is datatable object which holds DB results.
Table tbl = new Table();
tbl.CssClass = "table table-striped table-bordered table-responsive";
TableRow tr;
TableCell tcEU, tcUS, tcUK, tcQty, tcEAN;
Label lbEU, lbUS, lbUK, lbQty, lbEAN;
TextBox tbEU, tbUS, tbUK, tbQty, tbEAN, tbToFocus = null;
foreach (DataRow dr in dtRighe.Rows)
{
tr = new TableRow();
//ean
tcEAN = new TableCell();
tbEAN = new TextBox();
tbEAN.ID = "txtEAN" + dr[0].ToString();
tbEAN.Width = new Unit(100, UnitType.Percentage);
tbEAN.Columns = 15;
tcEAN.Controls.Add(tbEAN);
tr.Controls.Add(tcEAN);
//Qty
tcQty = new TableCell();
tbQty = new TextBox();
tbQty.ID = "txtQty" + dr[0].ToString();
tbQty.TextMode = TextBoxMode.Number;
tcQty.Controls.Add(tbQty);
tr.Controls.Add(tcQty);
tbl.Controls.Add(tr);
}
Session["tbl"] = tbl;
divTaglieRighe.Controls.Add(tbl);
}
When I click the button SAVE, I have to loop throug my table and save all the TextBox.Text...
this is what I wrote:
ArrayList arrScarpaFigli = new ArrayList();
Table tbl = (Table)Session["tbl"];
foreach (TableRow row in tbl.Rows)
{
foreach (TableCell cell in row.Cells)
{
foreach (Control ctrl in cell.Controls)
{
//CONTROL IS TEXBOXT: EXTRACT VALUES//
if (ctrl is TextBox)
{
TextBox txt = (TextBox)ctrl;
arrScarpaFigli.Add(txt.Text);
}
}
}
}
The problem is that, also if I fill the textboxes, in my Text there is always an empty string.
The only moment when I fill the table is on the selectionChange of a Dropdown.
What I'm doing wrong?
Thanks in advance
You have to recreate dynamic controls on every page load to make sure their values are retained after a PostBack. So you need to create a new Method that handles the creation of the Table every time the page is loaded.
protected void Page_Load(object sender, EventArgs e)
{
//always create the controls on every page load if there is a value selected in ddlScalaTaglie
if (!string.IsNullOrEmpty(ddlScalaTaglie.SelectedValue))
{
createTable(ddlScalaTaglie.SelectedValue);
}
}
protected void Button1_Click(object sender, EventArgs e)
{
//use findcontrol to find the Table inside the placeholder
Table tbl = Page.FindControl("divTaglieRighe").FindControl("Table1") as Table;
//loop all rows and cells in the Table
foreach (TableRow row in tbl.Rows)
{
foreach (TableCell cell in row.Cells)
{
foreach (Control ctrl in cell.Controls)
{
//the control is a textbox
if (ctrl is TextBox)
{
//cast the control back to a textbox
TextBox tb = ctrl as TextBox;
//does the checkbox have a value, if so append the label
if (!string.IsNullOrEmpty(tb.Text))
{
Label1.Text += tb.Text + "<br>";
}
}
}
}
}
}
protected void ddlScalaTaglie_SelectedIndexChanged(object sender, EventArgs e)
{
//no need to create the Table dynamically, that will be handled in Page_Load
//this method is just a dummy to trigger a PostBack
//you could remove this method and the OnSelectedIndexChanged from the DropDown
//and just keep the AutoPostBack="true", that will also work
}
private void createTable(string value)
{
DataTable dtRighe = Common.LoadFromDB();
//create a new table WITH id, that is needed for findcontrol
Table tbl = new Table();
tbl.ID = "Table1";
//loop all rows in the datatable
foreach (DataRow dr in dtRighe.Rows)
{
TableRow tr = new TableRow();
//ean
TableCell tcEAN = new TableCell();
TextBox tbEAN = new TextBox();
tbEAN.ID = "txtEAN" + dr[0].ToString();
tbEAN.Width = new Unit(100, UnitType.Percentage);
tbEAN.Columns = 15;
tcEAN.Controls.Add(tbEAN);
tr.Controls.Add(tcEAN);
//Qty
TableCell tcQty = new TableCell();
TextBox tbQty = new TextBox();
tbQty.ID = "txtQty" + dr[0].ToString();
tbQty.TextMode = TextBoxMode.Number;
tcQty.Controls.Add(tbQty);
tr.Controls.Add(tcQty);
tbl.Controls.Add(tr);
}
//add the table to the placeholder
divTaglieRighe.Controls.Add(tbl);
}
The aspx to make the example complete
<asp:DropDownList ID="ddlScalaTaglie" runat="server" OnSelectedIndexChanged="ddlScalaTaglie_SelectedIndexChanged" AutoPostBack="true">
<asp:ListItem Text="Select..." Value=""></asp:ListItem>
<asp:ListItem Text="Option 1" Value="1"></asp:ListItem>
<asp:ListItem Text="Option 2" Value="2"></asp:ListItem>
</asp:DropDownList>
<br />
<br />
<asp:PlaceHolder ID="divTaglieRighe" runat="server"></asp:PlaceHolder>
<br />
<br />
<asp:Button ID="Button1" runat="server" Text="Save" OnClick="Button1_Click" />
<br />
<br />
<asp:Label ID="Label1" runat="server" Text=""></asp:Label>
Storing an instance of Table control in Session is a terrible idea and is just plain wrong. Controls belong to their parent page - they should be added to it as soon as they are created and they should die with their parent page.
The thing with dynamically created controls in ASP.NET is that you have to store an indicator of the fact that they were created (together with relevant information needed to create them again) and recreate them on all subsequent postbacks - no later than in Page_Load. Only then these controls will have the chance of getting their values from Request and you will have the chance of obtaining these values from controls.
In your code, the instance of Table stored in Session (together with all its rows, cells and textboxes) will never reflect any client-side data changes, nor will it belong to Pages that will be created to process subsequent postback requests.
Update
The important fact to understand here is that, after processing the postback caused by ddlScalaTaglie change and returning hew html to the client, the page instance is gone. On next request a new instance of your page is created - and it does not know anything about the fact that the previous instance had table added to its control tree. It is your code in Page_Load that must discover that the form must have this table, and create the table in exactly the same way it was created the first time - with rows, cells and textboxes with exactly the same IDs.
Then, after you add this newly created table to divTaglieRighe.Controls, the textboxes will be able to extract their client-side values from Request.Form collection.
Make sure the textbox has a "name" for the post back to the controller.
If it does not it grabs a null for the parameter.
Check Request.Form for data returned to controller.
You've created a Table called tbl and added two TextBox, then you store Table control in session Session["tbl"] and added to divTaglieRighe control. Finally you are trying to get TextBox data from your session Session["tbl"] table not the ViewState control that added in divTaglieRighe control. You have to get data from you Table tbl control that added in divTaglieRighe control.
I have drop-down inside of a gridview so when the gridview is loaded and the drop-down is bound then the drop-down only show the first value of the drop-down list and it is not showing the previously selected value. When the gridview loads, i would like the drop-down to show what was previously selected for that row. Here is my code:
aspx markup for the drop-down:
<asp:TemplateField HeaderText="Answer">
<ItemTemplate>
<asp:Label ID="lblAns" runat="server" Text='<%# Eval("DDL_ANS")%>' Visible="false"></asp:Label>
<asp:DropDownList ID="ddl_Answer" runat="server">
</asp:DropDownList>
</ItemTemplate>
Here is code behind:
protected void RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DropDownList ddl_Answer;
//get current index selected
int current_quest = Convert.ToInt32(GridView1.DataKeys[e.Row.RowIndex].Value);
ddl_Answer = e.Row.FindControl("ddl_Answer") as DropDownList;
using (SqlConnection con2 = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["myconnection"].ConnectionString))
{
con2.Open();
using (SqlCommand cmd1 = new SqlCommand("select distinct DD_ANSWER from table1 where ID= '" + current_quest + "' ", con2))
{
ddl_Answer.DataSource = cmd1.ExecuteReader();
ddl_Answer.DataTextField = "DD_ANSWER";
ddl_Answer.DataValueField = "DD_ANSWER";
ddl_Answer.DataBind();
}
con2.Close();
}
}
I have tried to add this line of code after binding but i get this error "Object reference not set to an instance of an object"
ddl_Answer.Items.FindByValue((e.Row.FindControl("lblAns") as Label).Text).Selected = true;
thanks
I believe in your SELECT you need to use current_quest_sk instead of current_quest
Aslo try to check for null before accessing your controls:
var ddl_Answer = e.Row.FindControl("ddl_Answer") as DropDownList;
var answerLabel = e.Row.FindControl("lblAns") as Label;
if(answerLabel !=null && ddl_Answer!=null)
{
ddl_Answer.Items.FindByValue(answerLabel.Text).Selected = true;
}
#afzalulh has a valid point remove quotes if current_quest_sk(ID) is an Integer in your table.
You should avoid SQL injection but that's a different topic.
Place a breakpoint in your code, and setup through it with your debugger.
Either you have a typo in one of your string names or you are looking at the wrong control.
Stepping through your code will help you see exactly what line of your code is causing the problem.
You could also put a try/catch block around the whole thing to help you isolate the problem. Once you find the problem, remove the try/catch block.
I am a litle confused with ASP.NET lifecycle event. I have a checkbox when it is checked, it will dynamically create labels and text boxes. This is done in checkbox oncheckchanged event.I have Ajax enabled on the checkbox without full postback.
Now in the newly created text boxes I am entering the values and when I click on the save button, in the button click event it would not even find the controls created. So how does the page viewstate remember the dynamic controls created in the checkbox events and then access it's values in the button save event?
Mark up:
<tr> <td> <asp:CheckBox ID="chkType" runat="server" Text="Medical Procedure" OnCheckedChanged="ChkMedicalProc_Clicked"></td></tr>
<tr><td colspan="2">
<asp:PlaceHolder ID="dyna" EnableViewState="true" runat="server"></asp:PlaceHolder>
</td></tr>
Code behind in the checkedchanged event:
TableRow tr = new TableRow();
TableCell tc1 = new TableCell();
TableCell tc2 = new TableCell();
Label lbl = new Label();
lbl.Text = string.Empty;
lbl.Text = (_queryParam[i].Param_Name + " (" + _queryParam[i].Param_Type + ") (" + _queryParam[i].Param_Length + ")").ToString();
lbl.Style.Add("font-size", "11px");
lbl.Style.Add("font-family", "Arial");
_txtBox = new TextBox();
_txtBox.ID = ctrlId;
_txtBox.CssClass = "textEntry";
_txtBox.Text = string.Empty;
_txtBox.Text = _queryParam[i].Param_Value;
tc1.Style.Add("width", "21.8%");
tc1.Controls.Add(lbl);
tc2.Controls.Add(_txtBox);
tr.Cells.Add(tc1);
tr.Cells.Add(tc2);
_tbl.Rows.Add(tr);
this.Master.FindControl("pagecontent1").FindControl("dyna").Controls.Add(_tbl);
Save button click event:
for (int i = 0; i < box.Count; i++)
{
TextBox boxValue= this.Page.Master.FindControl("pagecontent1").FindControl("dyna").FindControl("txtBoxParams-" + i) as TextBox;
//I get object reference error on boxValue
}
Dynamic controls are lost on postback, so on every page request you must dynamically add them again.
Though for your example, it might be easier to always have the label / textbox on the page, but contain it in an asp:panel which you toggle the Visible property on it, or show/hide it via javascript.
As for the values of these dynamic controls during postback, if you re-create them using the same ID, asp.net will automatically re-initialize them to the proper inputted values using the viewstate information.
For more information about dealing with dynamic controls, this website seems to be fairly accurate: https://web.archive.org/web/20211020131055/https://www.4guysfromrolla.com/articles/081402-1.aspx
Using the following recursive function you will be able to retrieve any control inside the dynamic table
public static Control DeepFindControl(Control c, string id)
{
if (c.ID == id)
{
return c;
}
if (c.HasControls())
{
Control temp;
foreach (var subcontrol in c.Controls)
{
temp = DeepFindControl((Control)subcontrol, id);
if (temp != null)
{
return temp;
}
}
}
return null;
}
to receive the values of the control after finding it you should know the name of the control and then you will receive the values in another new created control with the same type... "cast the control returned from the DeepFindControl" e.g....
Control C1 = DeepFindControl(DynamicTableName, ControlNAme);
TextBox _txtBox = (TextBox)C1;
I am trying to create a UI that creates rows that can be dynamically populated.
I am at the point where I can add a Panel to my list that contains a DropDownList and has an associated Remove Button.
The Remove Button has an OnClick event bound that allows me to remove that specific panel.
I am having an issue when trying to bind a SelectedIndexChanged EventHandler to my DropDownList it does not.
I suspect this had something to do with how I am recreating my controls after every Postback.
I am not asking for or expecting a straightforward "Add this or Change this in the code." I really want to have a understand where I am going wrong, sorry for asking so much! :s
protected void Page_Load(object sender, EventArgs e)
{
//Showing this for the the poster that asked.
if (!IsPostBack)
{
GetClustersFromDB(user);
BindGrid();
BindState();
}
if (Session["persistControls"] != null)
{
persistControls = (List<Panel>)Session["persistControls"];
int count = 0;
foreach (Panel dynamicControl in persistControls)
{
DropDownList list = new DropDownList();
list.ID = "list" + count;
list.SelectedIndexChanged += new EventHandler(list_SelectedIndexChanged);
list.AutoPostBack = true;
list.Items.Add(new ListItem("", "0"));
list.Items.Add(new ListItem("Title", "1"));
dynamicControl.ID = "panel" + count;
Button btnRemove = new Button();
btnRemove.Click += new EventHandler(btnDelete_Click);
btnRemove.Text = "Remove";
btnRemove.CommandArgument = count.ToString();
myPlaceholder.Controls.Add(dynamicControl);
myPlaceholder.Controls.Add(btnRemove);
count++;
}
}
}
protected void btnAdd_Click(object sender, EventArgs e)
{
try
{
DropDownList list = new DropDownList();
list.SelectedIndexChanged += new EventHandler(list_SelectedIndexChanged);
list.AutoPostBack = true;
list.Items.Add(new ListItem("", "0"));
list.Items.Add(new ListItem("Title", "1"));
Panel panelContainer = new Panel();
panelContainer.ID = "panel" + persistControls.Count;
panelContainer.Controls.Add(list);
Button btnRemove = new Button();
btnRemove.Click += new EventHandler(btnDelete_Click);
btnRemove.Text = "Remove";
btnRemove.CommandArgument = persistControls.Count.ToString();
myPlaceholder.Controls.Add(panelContainer); // Pushes the Panel to the page.
persistControls.Add(panelContainer);// Adds our Panel to the Control list
myPlaceholder.Controls.Add(btnRemove); // Pushes our Button to the page.
Session["persistControls"] = persistControls; // put it in the session
}
catch
{
throw;
}
}
protected void btnDelete_Click(object sender, EventArgs e)
{
try
{
int deleteThisOne = int.Parse(((Button)sender).CommandArgument);
persistControls.Remove(persistControls[deleteThisOne]);
Session["persistControls"] = persistControls;
Response.Redirect(Request.Url.ToString());
}
catch
{
throw;
}
}
protected void list_SelectedIndexChanged(object sender, EventArgs e)
{
throw new NotImplementedException();
}
//aspx File Snippets
<asp:Button ID="btnAdd" runat="server" Text="Add Control" onclick="btnAdd_Click" />
<asp:Button ID="btnClear" runat="server" Text="Reset" onclick="btnClear_Click"/>
<asp:PlaceHolder ID="myPlaceholder" runat="server"></asp:PlaceHolder>
Maintaining controls like this is a real pain. You could try an alternative approach:
Create a (small) class that encapsulates the data you want to display in each Panel.
Maintain a List of these objects in Session.
Use an <asp:Repeater> to display the items by data-binding it to your list.
In the repeater's ItemTemplate, you can write out your <asp:Panel> that can contain a <asp:DropDownList>. Use the ItemCommand property of the drop-down list to bind it to a server-side event handler. Similarly you can put an <asp:Button> in the template and bind the ItemCommand property of this to another server-side event handler.
When you click Add, you'll postback to the server, add to your list, save it in session, re-bind the repeater.
When you click a Remove, you'll postback to the server, remove the item from your list, save it in session, re-bind the repeater.
This way lets ASP.Net handle all the control creation for you. However, if you really want to do all that yourself, then this Infinities Loop blog post is required reading.
I don't think this will work. If you create the dropdownlists in the PageLoad event, the viewstate will never get bound to it, and you will never see the option selected by the user.
You should create the controls OnInit, then when the PostBack occurs the ViewState data will get bound to the control and you will be able to access it.
I am trying to get an application to allow a user to select something for a number rows and then do something on the server side once the user submits the form. The problem I'm having is that if I reload the table, I just get the default values back and if I don't, the table is empty. Here is the code:
<asp:Table ID="tbl" runat="server">
<asp:TableRow>
<asp:TableHeaderCell>Question</asp:TableHeaderCell>
<asp:TableHeaderCell>Answer</asp:TableHeaderCell>
</asp:TableRow>
</asp:Table>
c#:
protected System.Web.UI.WebControls.Table tbl1;
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
init_tbl();
}
}
protected void init_tbl()
{
tbl1.BorderWidth = 1;
TableRow tr = new TableRow();
tc = new TableCell();
tc.Text = "text";
tc.BorderWidth = 1;
tr.Cells.Add(tc);
ddl = new DropDownList();
ddl.ID = "r" + index;
ddl.Attributes["runat"] = "server";
ListItem item;
for (int i = 1; i <= 10; i++)
{
item = new ListItem();
item.Text = i.ToString();
item.Value = i.ToString();
if (i.ToString().Equals(r.Trim()))
{
item.Selected = true;
}
ddl.Items.Add(item);
}
list.Add(ddl);
tc.Controls.Add(ddl);
tc.ID = "tblr" + index;
tr.Cells.Add(tc);
tbl1.Rows.Add(tr);
}
your problem is with the convoluted way asp.net deals with dynamic controls, you need to create the dynamic control on page init, before the view state is set so state of the controls is maintained on the post, see this article http://geekswithblogs.net/shahed/archive/2008/06/26/123391.aspx.
You should definatley look at the gridview or at the very least one of the repeater controls.
I would just make a list of questions and DataBind them to a repeater/gridview/datagrid (as #Cybernate said), then add an Event method to the OnItemDataBound of the databinder.
In the ItemDataBound event I would get a list of answers for each question DataItem and add them to a DropDownList like you were doing above.
When the user fills out all of the answers you just need to go through the Request.Form array and find all the answers that will be passed back.
You stored the Table in the ViewState and Use it as you want.