How to get the RadToolbarDropDown selected item value in code behind file. In my case I have a RadToolBar in which I dynamically create RadToolBarDropDown. I set these DropDown Value and Text dynamically as I my code shows.
RadToolBarDropDown dd = new RadToolBarDropDown();
if (ds.HasRows())
{
DataTable dt = ds.Tables[0];
foreach (DataRow row in dt.Rows)
{
RadToolBarButton rtb = new RadToolBarButton();
rtb.Text = row["Description"].ToString();
rtb.Value = row["ProblemStatusID"].ToString();
rtb.CommandName = "StatusChange";
rtb.CommandArgument = row["ProblemStatusID"].ToString();
dd.Buttons.Add(rtb);
}
}
RadToolBarItem item = dd;
mlmToolBar.Items.Add(item);
Now I want to get selected item value in cs when command name "StatusChange" fire. I want to get the clicked value of the dropdown. How I can get the clicked dropdown value?
There are 2 ways you can handle the button click event of the dropdown items. You can handle it on server side or you can handle it on client side. Lets look at it one by one:
Server Side:
Assume I have a rad tool bar control on my page. Here is the code for the same:
<telerik:RadToolBar runat="server" ID="rtlMyToolBar"
OnButtonClick="rtlMyToolBar_ButtonClick" ></telerik:RadToolBar>
Note that I have handled the OnButtonClick event. We will look at it next.
From code behind I am adding a dropdown control and adding buttons to the drop down. Here is the code for the same:
RadToolBarDropDown dd = new RadToolBarDropDown("Drop Down - Handled Server Side");
RadToolBarButton rtb = new RadToolBarButton();
rtb.Text = "Bold";
rtb.Value = "Bold";
rtb.CommandName = "Bold";
rtb.CommandArgument = "Bold";
dd.Buttons.Add(rtb);
rtb = new RadToolBarButton();
rtb.Text = "Italic";
rtb.Value = "Italic";
rtb.CommandName = "Italic";
rtb.CommandArgument = "Italic";
dd.Buttons.Add(rtb);
rtb = new RadToolBarButton();
rtb.Text = "Underline";
rtb.Value = "Underline";
rtb.CommandName = "Underline";
rtb.CommandArgument = "Underline";
dd.Buttons.Add(rtb);
rtlMyToolBar.Items.Add(dd as RadToolBarItem);
Now lets take a look at the event handler:
protected void rtlMyToolBar_ButtonClick(object sender, RadToolBarEventArgs e)
{
var toolBarButton = e.Item as RadToolBarButton;
string commandName = toolBarButton.CommandName;
if (commandName == "YourCommandName")
{
//Your logic
}
}
Client Side:
Now lets take a look at how to listen to drop down button click on the client side. Here is the code snippet for the rad tool bar:
<telerik:RadToolBar runat="server" ID="rtlMyToolBar2"
OnClientButtonClicked="OnClientButtonClicked"></telerik:RadToolBar>
Note that now I am listening to OnClientButtonClicked event. The event handler is a javascript function reference.
Here is the javascript code:
<script>
function OnClientButtonClicked(sender, args) {
$("#status").append("OnClientButtonClicked: " + args.get_item().get_text() +
" - Command Name: " +
args.get_item().get_commandName() + "<br/>");
}
</script>
All telerik controls have a rich consistent client side and server side API.
Here is the GIST link for the above code: https://gist.github.com/lohithgn/5329716
Here is a example which show cases the client side api in our live demo site: http://demos.telerik.com/aspnet-ajax/toolbar/examples/clientside/clientevents/defaultcs.aspx
Here is the client side API basics help documentation:
http://www.telerik.com/help/aspnet-ajax/toolbar-clientsidetoolbaritem.html
Thanks
Related
I am creating asp.net web form. in that i am creating dynamic tables in which particular column is numeric text box control.
i don't know how to assign and get values from the text box control.. my coding as follow..
for (int i = 0; i < my_DataTable.Rows.Count; i++)
{
HtmlTableRow _Row = new HtmlTableRow();
HtmlTableCell Col = new HtmlTableCell();
Col.InnerText = my_DataTable.Rows[i]["itmCode"].ToString();
_Row.Controls.Add(Col);
Col = new HtmlTableCell();
_Row.Controls.Add(Col);
Col.InnerHtml = "<input type='number' value='0'>";
_Row.Controls.Add(Col);
my_Table.Rows.Add(_Row);
}
In a paricular method, i need to assign the value to the text box control also needs to get the value existing value.. so i try follow as below
var no_1 = my_Table.Rows[0].Cells[1].InnerText;
If i check the no_1, it has the textbox, but i don't know how to access the current value and assign new value..
can anyone help me how to achieve this..
One thing you have to keep in mind while working with Dynamic Controls is that whenever a postback has occurred you will lose the dynamically created controls(as the postback calls the Page_load() event so if you don't have them at the load event they will not be generated and hence will not be displayed.). So, it is always better to re-render the controls in the load event.
So, in order to get the value of the dynamically assigned controls (either HTML or Asp.net) here is how i would do that.
First, create a holder which will be used to store the controls in the page either with runat="server"(So, you can access that control in the backend). In your case, that control is my_Table. Then use the Session/ViewState to keep a track of all the created dynamic controls which can be used re-render the controls with their values as:
To add a new control in the page it would be like this:
var cnt = _findRelated("txtDynamic") + 1; //for all the dynamic text boxes i am using the prefix of txtDynamic just to keep SOC.
var nId = $"txtDynamic-{cnt}";
var _ctrl = new HtmlInputText("Integer")
{
Name = nId,
ID = nId,
//Value="Default Value" //uncomment to assign a default value
};
_ctrl.Attributes.Add("runat", "server");
var row = new System.Web.UI.HtmlControls.HtmlTableRow();
var newCell = new HtmlTableCell();
newCell.Controls.Add(_ctrl);
row.Cells.Add(newCell);
my_Table.Rows.Add(row);
Session.Add(cnt.ToString(), _ctrl); //here i am using session to manage the controls but you can also use the ViewState
In the above code i am using HtmlInputText to generate an <input type="number"></input> with it's constructor taking the type string more can be read at:HtmlInputText.
The _findRelated() method is used to get the number of dynamic text controls appended to the Form. It is defined as:
private int _findRelated(string prefix)
{
string reqstr = Request.Form.ToString();
return ((reqstr.Length - reqstr.Replace(prefix, "").Length) / prefix.Length);
}
To set the value of the dynamically added control we can do something like this(if not assigned at the creation):
var cell = my_Table.Rows[_myTable.Rows.Count-1].cells[0]; //here i have assumed it is in the last row and in the first cell you can change the index to be anything.
var txtDynamic = cell.Controls.OfType<HtmlInputText>().FirstOrDefault();//getting the control
txtDynamic.Value = "<Some thing new>"; //setting the value
Now, to get the assigned the value:
var cell = my_Table.Rows[_myTable.Rows.Count-1].cells[0]; //here i have assumed it is in the last row and in the first cell you can change the index to be anything.
var txtDynamic = cell.Controls.OfType<HtmlInputText>().FirstOrDefault();//getting the control
//now use the .Value property of the control to get the value as:
var nValue = txtDynamic.Value;
And as we know the dynamically added controls will be lost on the postback event then we can create a method which will use the controls stored in the Session and re-render them with their values as:
private void _renderControls()
{
try
{
if (Session.Count > 0)
{
for (int k = 0; k < Session.Count; k++)
{
if (Session[k] != null)
{
var _ctrl = new HtmlInputText("Integer") //you can make it dynamic to add different types of input control
{
Name = ((HtmlInputText)Session[k]).ID,
ID = ((HtmlInputText)Session[k]).ID,
Value = ((HtmlInputText)Session[k]).Value
};
if (_ctrl != null)
{
_ctrl.Attributes.Add("runat", "server");
var row = new System.Web.UI.HtmlControls.HtmlTableRow();
var newCell = new HtmlTableCell();
newCell.Controls.Add(_ctrl);
row.Cells.Add(newCell);
my_Table.Rows.Add(row);
}
}
}
}
}
catch (Exception ex)
{
throw ex;
}
}
Now, let's modify the Page_load() event to call this method on every postback as:
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
_renderDynamic(); // this method will be called if there is an postback event to re-render the dynamic controls
}
}
Note:
This is just a sample(there can be a lot better approaches out there).
I have used HtmlInputText with property as Integer to create ainput[type="number"].
If i have method like this to Draw my side Menu Dynamically :
private void DrawSideMenu()
{
LinkButton x;
TaskDTO TaskList = new TaskDTO();
List<TaskDTO> List = TaskList.DrawMenu(int.Parse(Session["emp"].ToString()));
HtmlGenericControl myDIV = new HtmlGenericControl("div");
myDIV.ID = "menu8";
HtmlGenericControl myOrderedList = new HtmlGenericControl("ul");//css clss for <ul>
myOrderedList.ID = "orderedList";
myOrderedList.Attributes.Add("class", "task");
HtmlGenericControl listItem1;
string count = "";
foreach (TaskDTO i in List)
{
count = AdjustMenuCount1(i.TaskCode);
x = new LinkButton();
x.ID = i.TaskCode.ToString();
x.Text = i.TaskName + " " + count;
x.Click += new EventHandler(TaskC);
x.Style["FONT-FAMILY"] = "tahoma";
listItem1 = new HtmlGenericControl("li");
listItem1.Attributes.Add("class", "normal");
if (count != "0")
{
listItem1.Controls.Add(x);
myOrderedList.Controls.Add(listItem1);
}
}
myDIV.Controls.Add(myOrderedList);
MenuTD.Controls.Add(myDIV);
Session["SideMenu"] = myDIV;//Save to redraw when page postbacks
}
This Method takes long time to draw my menu.so i call it one time in (!IsPostBack) and save it in session so that i could redraw it like that :
MenuTD.Controls.Add( ((System.Web.UI.Control)(Session["SideMenu"])));
It redraws it successfully but when i click on any link it doesn't hit the event because i thought it's not possible to save the x.Click += new EventHandler(TaskC); in the session ,so i want to know how to loop through my session content to resetting the delegate of my link ?
That idea won't work because if you're not wiring up the Event Handler every time the page is loaded, it won't run.
If we come back to the original issue, you said it's slow. Creating controls at runtime cannot be slow and it's most likely the way you create your list of items:
List<TaskDTO> List = TaskList.DrawMenu(int.Parse(Session["emp"].ToString()));
Instead of storing complete menu, try to store in the Session only List and create all controls as usual. If menu is required on one page only, then use ViewState instead of Session.
Also it makes sense to change the entire code as currently you hardcode all style and layout settings in the code. Create all layout (div, ul, li) in aspx, move all styles in css (for example, you use "task" class but still set "tahoma" in the code). This would simplify the code and bring more flexibility.
List<TaskDTO> List = null;
void Page_Load(object sender, EventArgs e)
{
if (ViewState["List"] != null) {
List = (List<TaskDTO>)ViewState["List"];
} else {
// ArrayList isn't in view state, so we need to load it from scratch.
List = TaskList.DrawMenu(int.Parse(Session["emp"].ToString()));
}
// Code to create menu, e.g.
if (!Page.IsPosBack) {
Repeater1.DataSource = List;
Repeater1.DataBind();
}
}
void Page_PreRender(object sender, EventArgs e)
{
// Save PageArrayList before the page is rendered.
ViewState.Add("List", List);
}
...
<ul id="orderedList">
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<li><%# Eval("TaskName") %></li>
</ItemTemplate>
</asp:Repeater>
</ul>
Maybe save it in application level so it only gets built once, then just put the menu into an object and loop through it to re-add the clicks.
I'm afraid that in order for it to work you are going to have to rebind the Click handler on every Page_Load.
Based on your code, and assuming your TaskC is available, you can make this method:
private void RebindMenuHandlers() {
if(Session["SideMenu"] == null)
return; // Your menu has not been built yet
var menu = ((System.Web.UI.Control)(Session["SideMenu"]));
var orderedList = menu.Controls[0];
foreach(var listItem in orderedList){
foreach(var control in listItem){
var linkButton = control as LinkButton;
if(linkButton != null){
linkButton.Click += new EventHandler(TaskC);
}
}
}
}
Then call it on your Page_Load event:
void Page_Load(object sender, EventArgs e)
{
RebindMenuHandlers();
// .... etc
}
I just typed this directly here, so please forgive any silly compilation mistakes, this should be enough to give you the general idea. Hope that helps.
I am trying to get an asp.net chart and it's legend to allow me to open up another page in another tab passing the values of the piece of the chart I clicked on with it. I have been able to get it to open up another tab when clicking on the chart by doing the following but it does not pass the data.
Chart2.Series[0].LegendUrl = "chartdetails.aspx";
Chart2.Series[0].Url = "chartdetails.aspx";
Chart2.Series[0].LegendMapAreaAttributes="target=\"_blank\"";
Chart2.Series[0].LegendPostBackValue = "#VALY-#VALX";
Chart2.Series[0].MapAreaAttributes="target=\"_blank\"";
Chart2.Series[0].PostBackValue = "#VALY-#VALX";
If I leave out the urls and mapareaattributes I can then get it to go to the onclick where I am able to get the data, put it in a session variable and use Reponse.Redirect to open the new page where it sees the session variable data,however it doesn't open in another tab, it opens in the same tab.
Chart2.Series[0].LegendPostBackValue = "#VALY-#VALX";
Chart2.Series[0].PostBackValue = "#VALY-#VALX";
protected void Chart2_Click(object sender, ImageMapEventArgs e)
{
HttpContext.Current.Session["VAL"] = e.PostBackValue;
Response.Redirect("chartdetails.aspx", false);
}
How can I get it to do both? Does Response.Redirect have a way to open a new tab? Some research leads me to believe it does not. Is there a way to get both the server side onclick event to run, so I can set the session variable and the chart.series.url to fire after the server side click runs so the session variable would be set before I open the new tab?
I'm feeling like this may be a case of "I can't have my cake and eat it too."
As it turns out I can have my cake and eat it too. If I set the url, postbackvalues, and legendmapareaattributes in my Page_Load and set up the click for the chart to put the PostBackValue in the session variable when you click on the chart it saves the value in the session variable that is listed in the PostBackValue of the Series of the chart. It then opens in a new tab chartdetails.aspx where I can access the information from the session variable.
Chart2.Series[0].LegendUrl = "chartdetails.aspx";
Chart2.Series[0].LabelUrl = "chartdetails.aspx";
Chart2.Series[0].Url = "chartdetails.aspx";
Chart2.Series[0].LegendPostBackValue = "#VALY-#VALX";
Chart2.Series[0].LabelPostBackValue = "#VALY-#VALX";
Chart2.Series[0].PostBackValue = "#VALY-#VALX";
Chart2.Series[0].LegendMapAreaAttributes = "target=\"_blank\"";
Chart2.Series[0].LabelMapAreaAttributes = "target=\"_blank\"";
Chart2.Series[0].MapAreaAttributes="target=\"_blank\"";
protected void Chart2_Click(object sender, ImageMapEventArgs e)
{
HttpContext.Current.Session["VAL"] = e.PostBackValue;
}
I can't use postback to get the value on the series for some reason. So, I want to share my way inspired by #Adam that is loop over the series points after data binding the chart and set URL.
GET:
Series s=new Series("Test");
/*
* After Data bind to the series s
*/
for (int p = 0; p < s.Points.Count; p++)
{
s.Points[p].Url ="test.aspx?name1=value1&name2=value2";
s.Points[p].MapAreaAttributes = "target=\"_blank\"";
}
POST:
(I put javascript function in url. So, It will execute the javascript for me to send a form I created in the function to the text.aspx.)
Series s=new Series("Test");
/*
* After Data bind to the series s
*/
for (int p = 0; p < s.Points.Count; p++)
{
s.Points[p].Url ="javascript:(function(){" +
"var mapForm = document.createElement('form');mapForm.target = '_blank';" +
"mapForm.method = 'POST';mapForm.action = 'test.aspx';" +
"var mapInput = document.createElement('input');mapInput.type = 'hidden';" +
"mapInput.name = 'partID';mapInput.value = 'put any value you need';" +
"mapForm.appendChild(mapInput);document.body.appendChild(mapForm);" +
"mapForm.submit();document.body.removeChild(mapForm);})();";
}
Reference:
Javascript pass values using POST
I'm creating a WPF C# application that has a datagrid hooked up to a SQL Server database. The user has the option of editing data in the datagrid by highlighting a row and clicking an edit button which then populates several textboxes with the data from the highlighted row. At this point, the user can then edit the data, click save and the datagrid reflects the changes. Until recently that feature was working fine. However, I was asked to add a feature that displays a highlighted row of data somewhere else on the screen (as looking at a datagrid for too long can become tiresome). So when a user clicks on a row a series of textblocks to the right of the datagrid change to show the data of the highlighted row in an easier to view format. That feature also works fine. The issue I'm having now, is that when a row is highlighted and automatically displays the data in the textblocks, if the user also tries to edit that row, the application crashes. The data displays just fine in the textboxes after the user clicks edit (while simultaneously displaying the same highlighted row in the textblocks); it's just when save is clicked that I run into an issue.
Debugging the program shows that everything is running smoothly. However after clicking save, the debugger jumps back up to my myGridSelectionChanged event and say's "NullReferenceException was unhandled -- Object reference not set to instance of an object" When I reload the program however, the datagrid reflects the changes that I tried to make before the application crashed. I'm assuming that means that the issue doesn't have to do with actually editing the database, rather the problem is with the textblocks not being able to reflect those edits. Below is some of my code:
Here is the code for the save button:
private void saveBtn_Click(object sender, RoutedEventArgs e)
{
var stqmDC = new SqtmLinqDataContext();
var selectedRow = EditGrid.GetSelectedRow(myGrid);
var ID = EditGrid.GetCell(myGrid, selectedRow, 0);
string selectedID = ((TextBlock)ID.Content).Text;
int convertedID = Convert.ToInt32(selectedID);
int newQuantity = int.Parse(quantityTxt.Text);
var query = from info in stqmDC.General_Infos
where info.Quote_ID == convertedID
select info;
foreach (General_Info info in query)
{
info.Customer_Name = customerNameTxt.Text;
info.OEM_Name = oemNameTxt.Text;
info.Qty = newQuantity;
info.Quote_Num = quoteNumberTxt.Text;
info.Fab_Drawing_Num = fabDrawingNumTxt.Text;
info.Rfq_Num = rfqNumberTxt.Text;
info.Rev_Num = revNumberTxt.Text;
}
try
{
stqmDC.SubmitChanges();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
var mainTable = from generalInfo in stqmDC.GetTable<General_Info>()
select new
{
generalInfo.Quote_ID,
generalInfo.Open_Quote,
generalInfo.Customer_Name,
generalInfo.OEM_Name,
generalInfo.Qty,
generalInfo.Quote_Num,
generalInfo.Fab_Drawing_Num,
generalInfo.Rfq_Num,
generalInfo.Rev_Num
};
myGrid.ItemsSource = mainTable;
leftSP.Visibility = Visibility.Hidden;
rightSP.Visibility = Visibility.Hidden;
cancelBtn.Visibility = Visibility.Hidden;
submitBtn.Visibility = Visibility.Hidden;
saveBtn.Visibility = Visibility.Hidden;
sendBtn.Visibility = Visibility.Hidden;
}
And the code for displaying the highlighted row in textblocks:
private void myGridSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var rowSelection = EditGrid.GetSelectedRow(myGrid);
var quoteID = EditGrid.GetCell(myGrid, rowSelection, 0);
string quoteIDEdit = ((TextBlock)quoteID.Content).Text;
QuoteIDtxtblk.Text = quoteIDEdit;
var date = EditGrid.GetCell(myGrid, rowSelection, 1);
string dateEdit = ((TextBlock)date.Content).Text;
Datetxtblk.Text = dateEdit;
var custName = EditGrid.GetCell(myGrid, rowSelection, 2);
string custNameEdit = ((TextBlock)custName.Content).Text;
CustomerNametxtblk.Text = custNameEdit;
var OemName = EditGrid.GetCell(myGrid, rowSelection, 3);
string OemNameEdit = ((TextBlock)OemName.Content).Text;
OemNametxtblk.Text = OemNameEdit;
var Quantity = EditGrid.GetCell(myGrid, rowSelection, 4);
string QuantityEdit = ((TextBlock)Quantity.Content).Text;
Quantitytxtblk.Text = QuantityEdit;
var quoteNum = EditGrid.GetCell(myGrid, rowSelection, 5);
string quoteNumEdit = ((TextBlock)quoteNum.Content).Text;
QuoteNumbertxtblk.Text = quoteNumEdit;
var fabDrawing = EditGrid.GetCell(myGrid, rowSelection, 6);
string fabDrawingEdit = ((TextBlock)fabDrawing.Content).Text;
FabDrawingNumbertxtblk.Text = fabDrawingEdit;
var rfqNum = EditGrid.GetCell(myGrid, rowSelection, 7);
string rfqNumEdit = ((TextBlock)rfqNum.Content).Text;
RfqNumbertxtblk.Text = rfqNumEdit;
var revNum = EditGrid.GetCell(myGrid, rowSelection, 8);
string revNumEdit = ((TextBlock)revNum.Content).Text;
RevNumbertxtblk.Text = revNumEdit;
}
Thanks in advance to anyone who can help.
Where exactly would you think it's handled?
To handle exceptions that cause app crashes you need to exception-proof every "entry point", defined as every spot in your app where unmanaged code can call in or a the code starts running on a different thread.
This includes button click handlers. Add a try/catch in your button handler and show some UI message that an error happened and write a log message or at least a 'Debug.WriteLine(exceptionObjectHere);' so you can see where did the exception come from
You change ItemsSource of a DataGrid in saveBtn_Click which means that your selection will disapear and SelectionChanged will be fired.
So you need to handle this case (myGrid.SelectedItem == null) somewhere, and just do nothing (return) if so.
I have Label controls in Panel controls that need to be updated. The Panel and Label controls are dynamically created. Now I need to find a way to get the value of 1 Label in a Panel.
C# Code
// Create Panel
Panel newpanel = new Panel();
newpanel.Name = "panel_" + reader.GetValue(0);
newpanel.Size = new Size(200, 200);
newpanel.BorderStyle = BorderStyle.FixedSingle;
newpanel.Parent = FlowPanel;
// Create Label
Label newipaddress = new Label();
newipaddress.Name = "lbl_ip_add";
newipaddress.Text = reader.GetValue(3).ToString();
newipaddress.Location = new Point(55, 175);
newipaddress.Parent = newpanel;
-------------
foreach (Panel p in FlowPanel.Controls)
{
string ip = !!! GET IP FROM LABEL !!!
Ping pingSender = new Ping();
IPAddress pingIP = IPAddress.Parse(ip);
PingReply pingReply = pingSender.Send(pingIP);
lbl_ping_1.Text = string.Format("Ping: {0}", pingReply.RoundtripTime.ToString());
if ((int)pingReply.RoundtripTime < 150)
{
lbl_ping_1.BackColor = Color.Green;
}
else if ((int)pingReply.RoundtripTime < 200)
{
lbl_ping_1.BackColor = Color.Orange;
}
else
{
lbl_ping_1.BackColor = Color.Red;
}
}
The string ip needs to get the IP from the Label. The IP is in string format that will be converted to the IP address as you can see.
How can I get the value of the dynamically created Label?
GUI Tools like labels really shouldn't hold the data, it should just show the data. So in your case, it would really be better to hold the label information in a local variable or dictionary.
In either case, you can search your panel's control collection for the label's name (control key):
string ip;
if (p.Controls.ContainsKey("ipLabel")) {
ip = p.Controls["ipLabel"].Text;
}
This assumes when you created your label, you named it "ipLabel":
Label ipLabel = new Label();
ipLabel.Name = "ipLabel";
Update:
You also need to add the controls to the container using the Controls collection instead of setting the Parent of the control.
Example:
newpanel.Controls.Add(newipaddress);
I would do this with the panel to the flowpanel control as well:
FlowPanel.Controls.Add(newpanel);
if you create the controls dynamically you should do so on every page generation. Best place to do this is in the PreInit event. Then you can have events and state just like normal controls in the OnLoad event.