Reading __EVENTTARGET causes event is not called - c#

I want to use information on which control was clicked for setting up the page. I use this to set up a sortable table in code. I found through this forum that I can use Request.Form.Get("__EVENTTARGET") for that. However, as soon as I do something with that parameter, the callback function is no longer called. Is this expected behavior or am I making a mistake?
Here some snippets of my code. The code in Page_Load() is:
string sortRequest = Request.Form.Get("__EVENTTARGET");
bool isCurrentField = false;
if (sortRequest != null) isCurrentField = sortRequest.Contains(header.Field);
if (!isCurrentField)
{
// Add a hyperlink for sorting to the cell
LinkButton newLink = new LinkButton();
newLink.Text = header.Title;
newLink.Font.Bold = true;
newLink.ID = "link" + header.Field;
newLink.CommandName = "Sort";
newLink.CommandArgument = header.Field;
newLink.Command += new CommandEventHandler(LinkButton_Command);
hdrCell.Controls.Add(newLink);
}
else
{
hdrCell.Text = header.Title;
hdrCell.Font.Bold = true;
}
My callback:
public void LinkButton_Command(Object sender, CommandEventArgs e)
{
_sortOrder = e.CommandArgument.ToString();
}
I have also tried it with copying the sortRequest into a temporary variable, but that doesn't make a difference. As soon as I comment out the line if (sortRequest != null) isCurrentField = sortRequest.Contains(header.Field);, the callback is called again.

There is a fault in your logic. You have a dynamically created control LinkButton with LinkButton_Command event handler connected to it. For the server-side event to fire on postback, the control must be present in the page control tree. This means the dynamic LinkButton must be created, configured and added to hdrCell.Controls always, regardless of sortRequest value. Only then will it be able to pick up the fact that it was clicked from the Request and fire its Command event.

Related

Referencing a UserControl from a another UserControl

I've got some embedded user controls in this project I'm stuck with and while trying to access a button state in the parent control my return value isn't what I'm expecting.
var parentControl = (OrderDetail)this.Parent.Parent;
// set return based on the OrderDetail control button state
UltraButton btn = parentControl.Controls.Find("btnReturn", true).FirstOrDefault() as UltraButton;
That always returns btn.Enabled = true back to me, even though when the form is done loading the button I am referencing here is not enabled. Is there a lifecycle thing I am just not aware of here?
Delving into winforms is rare for me, so I'm sure I'm missing something, just not sure what it is yet.
Thanks!
Placed my code into the OnVisibleChanged event.
protected override void OnVisibleChanged(EventArgs e)
{
base.OnVisibleChanged(e);
if (Visible && !Disposing)
{
// set return change option based on the OrderDetail control button state
UltraButton btn = parentControl.Controls.Find("btnReturn", true).FirstOrDefault() as UltraButton;
if (btn != null && (HasPermissions && btn.Enabled))
actionAllowed = true;
}
}

Asp.NET server control events not firing

Thanks for all who reads. I have a code issue that has been discussed many times on stackoverflow, but I can't make the provided solutions work.
It's about server control that contain other controls and I can't fire their events.
My issue is simple, i need to add any numbers ok LinButton into my server control. this is my code:
protected override void CreateChildControls()
{
for (int i = 0; i < IndiceValue; i++)
{
LinkButton imageTemp = new LinkButton() { CommandName = String.Format("{1}_{0}", CommandNames, i), Text = i.ToString(), ID = Guid.NewGuid().ToString()};
imageTemp.Click += ImageTempOnClick;
this.Controls.Add(imageTemp);
}
base.CreateChildControls();
}
I have a custom event in my control:
public delegate void IndiceFiabiliteCommand(object sender, IndiceFiabiliteCommandEventArg e);
public event IndiceFiabiliteCommand Command;
And theorically, when any of the LinkButton is clicked, I want the user to be warn that any of the LinkButton has been clicked. I give him all the needed infos but i don't think this part is the problem.
Last thing to know is that I implement INamingContainer and I tried to implement both, IPostBackDataHandler and IPostBackEventHandler but it didn't worked.
I hope it's understandable enough
thanks!
The problem is ID = Guid.NewGuid().ToString()
You cannot have dynamically created control with dynamic id. Change the code to
... i.ToString(), ID = i.ToString()
Basically, dynamic control's ID must be same as the ID originally created.
Otherwise, new control is created on every post-back, and it cannot find the control which causes the post-back.
FYI: if you need to catch an event, I would like to suggest to use CompositeControl which already have INamingContainer.
Note: it is just what I found based on your code; it might be other issue too.

C# Code-behind control form execution

I have a form that I would like to reuse for both adding a new record and editing an existing record. I am able to successfully load the page with the relevant data when I select a record from a GridView and I am able to update the db record appropriately. However, my issue is trying to use the form for both executions. Here is my logic in code behind: (I assign a session variable when I click on the row in GridView and this does work successfully)
protected void Page_Load(object sender, EventArgs e)
{
resultOutput.Visible = false;//Output results as to whether or not a record was added successfully is automatically hidden at page load
//Checking to see if session variable has been created
if (Session["editID"] != null)
{
//Create objects to get recipe data
dbCRUD db = new dbCRUD();
Recipe editRecipe = new Recipe();
//Grabbing session ID and assigning to a variable in order to remove the session variable
var id = Convert.ToInt32(Session["editID"]);
Session.Remove("editID");
//Call method to retrieve db data
editRecipe = db.SelectRecord(id);
//Populate results to text boxes
recordID.Text = id.ToString();
addName.Text = editRecipe.Name;
addTypeDDL.SelectedValue = editRecipe.Meal;
addDifficultyDDL.SelectedValue = editRecipe.Difficulty;
addCookTime.Text = editRecipe.Cook_Time.ToString();
addDirections.Text = editRecipe.Directions;
//Change Button Text
submitRecord.Visible = false;
changeRecord.Visible = true;
//Change Title Text
addEditTitle.Text = "Edit Recipe";
}
}
protected void submitRecord_Click(object sender, EventArgs e)
{
//Variables for execution results
var modified = "";
int returned = 0;
//Creating the recipe Object to pull the values from the form and
//send the recipe object as a parameter to the method containing insert stored procedure
//depending on Add or Edit
Recipe recipe = new Recipe();
recipe.Name = addName.Text;
recipe.Meal = addTypeDDL.Text;
recipe.Difficulty = addDifficultyDDL.Text;
recipe.Cook_Time = int.Parse(addCookTime.Text);
recipe.Directions = addDirections.Text;
//Creating object to access insert method
dbCRUD newRecord = new dbCRUD();
//Checking to see if the page is loaded for edit or new addition
if (Session["editID"] != null)
{
//If recordID exists, recipe will be passed as to UpdateRecord method
recipe.Recipe_ID = int.Parse(recordID.Text);
returned = newRecord.UpdateRecord(recipe);
modified = "has been edited.";
Session.Remove("editID");
}
else
{
//If recordID does not exist, record will be passed to InsertRecord method (new recipe)
returned = newRecord.InsertRecord(recipe);
modified = "added";
}
//Method returns 0 if successful, 1 if sql error, 2 if other error
if (returned == 1)
{
resultOutput.Text = "There was an sql exception";
resultOutput.Visible = true;
}
else if (returned == 2)
{
resultOutput.Text = "There was a non sql exception";
resultOutput.Visible = true;
}
else
{
resultOutput.Text = "\"" + addName.Text + "\" recipe " + modified;
resultOutput.Visible = true;
}
}
I have issues on the if(Session["editID"] != null) line - I am always moved to the else logic and the if logic never runs.
Here is my click method in the GridView:
protected void Grid_Recipe_SelectedIndexChanged(object sender, EventArgs e)
{
int index = Convert.ToInt32(Grid_Recipe.SelectedDataKey.Value);
Session["editID"] = index;
Response.Redirect("addRecord.aspx");
}
My question is how can I control execution during the submitRecord_Click event so that I call the appropriate method. Thanks!
Have you considered using
if(Page.IsPostBack)
{
code here
}
To detect whether you are posting back to the page? Then you could check your value of the item. I see no reason the code shouldn't be in the Session variable - have you tried putting a breakpoint in there to see if the code actually gets in there?
Also does your addRecord.aspx just add the record? If so, just add the record in this class, but use the PostBack check to see. Could you just make sure you are saving in the right context aswell:
// Outside of Web Forms page class, use HttpContext.Current.
HttpContext context = HttpContext.Current;
context.Session["editID"] = index;
...
int Id = (string)(context.Session["editID"]);
I was able to figure out my issue - which actually turned into two issues. First, I had to put my Page Load logic in a if(!IsPostBack) statement because I could not edit the page. Reason being is I was loading the originally posted data to the form on page load, which executed before my logic. Adding the if(!IsPostBack) control statement fixed this issue. From there, I'm still using a session variable to control code behind logic, only I made sure keep my session variable only between the form and the gridview. Basically, when the gridview loads and it is not a post back, the session variable is cleared. This let's me set a new session variable when I click on a row and then the session variable is cleared once I return to the grid to see the results. Thanks for the help!

Adding EventHandler for dynamically added control

I've got a problem with adding some controls into a Panel(which gets "PopUpped" by a ModalPopupExtender) and add a CheckedChanged-EventHandler.
First of all, when user clicks on a button, this happens inside the CreatePanelChoose() function:
foreach (ListItem item in lbSupplier.Items)
{
string cbid = "cb" + i;
CheckBox cb = new CheckBox();
cb.ID = cbid;
cb.Text = item.Text;
cb.AutoPostBack = true;
AjaxControlToolkit.MutuallyExclusiveCheckBoxExtender mecbe = new AjaxControlToolkit.MutuallyExclusiveCheckBoxExtender();
mecbe.ID = "mecbe" + cbid;
mecbe.TargetControlID = cbid;
mecbe.Key = "SupplierKEY";
mecbe.BehaviorID = mecbe.ID + i;
//Also adding a Label
phModalPopupExtender.Controls.Add(new LiteralControl("</br>")); //phModalPopupExtender is a PlaceHolder
phModalPopupExtender.Controls.Add(cb);
phModalPopupExtender.Controls.Add(mecbe);
phModalPopupExtender.Controls.Add(lbl);
AsyncPostBackTrigger trigger = new AsyncPostBackTrigger();
trigger.ControlID = cbid;
trigger.EventName = "CheckedChanged";
UpdatePanelMatrix.Triggers.Add(trigger);
i++;
ButtonOK.Enabled = false;
}
lblText.Text = "Select one Supplier";
ModalPopupExtender1.Show();
Then i add the EventHandler in the Page_LoadComplete:
As you can see it also gets asigned to the control (I think).
The ModalPopup shows up correctly, but if I click one of the CheckBox, then it just closes it without going into cb_CheckedChanged, but it makes a Async postback ...
If I check Request.Form["__ASYNCPOST"] its true and Request.Form["__EVENTTARGET"] is also correct. (It gives me the unique id!)
Request.Form["__EVENTARGUMENT"] is empty.
I think I also need to say that I use a masterpage.
The problem shouldn't be the lifecycle of the page, because msdn says:
LoadComplete
Raised at the end of the event-handling stage.
Use this event for tasks that require that all other controls on the page be loaded.
Its the onliest place it makes me think it would be right.
Btw: yes i looked trough the topics here allready, but nothing helped me ... (google fo sure also)
Edit 1:
if (IsPostBack)
{
if (recreating == true)
{
CreatePanelChoose();
}
}
In CreatePanelChoose i do the foreach now everytime when its a postback! But it still doesnt fire cb_ChangedChecked ...
Edit 2:
MSDN-Page-Lifecycle also says:
PreInit
Raised after the start stage is complete and before the initialization
stage begins.
Use this event for the following:
Create or re-create dynamic controls.
So i tried to recreate the Panel there. But i dont have the ListItems there to get the values ... ?!
Okay, gave up ...
If someone would still have an answer, it would be great!
Right now I dont use the OnCheckedChanged-Event of the CheckBoxes anymore.
I just let them select a CheckBox and on the OnClick of the ButtonOk I loop through the CheckBoxes and check which one is selected.

Dynamically changing css style in c#?

I have some link buttons in which I am dynamically adding a style to it. I am doing the following in a method:
LinkButton lb = new LinkButton();
lb.Style["font-weight"] = "bold";
When the another link is clicked, it should unbold the link button that is bold and bold the currently clicked one, so in the method that is doing this, I have tried:
lb.Style["font-weight"] = "none";
The above does not work though, the previously selected link stays bold.
I just realized the possible problem. I am creating multiple links and what it looks like is that since all the links are named lb, it never removes the bold. I am trying to think of a way for it to remember the previously selected link and to only unbold that one.
Can I suggest an alternative approach?
Set a CSS Style:
.selected { font-style: bold; }
When a link is clicked set that link's CSS class to "selected" and the others to "";
EDIT: To accommodate for existing Css Class
const string MY_CLASS = "links";
lb1.CssClass = MY_CLASS + " selected"; // selected
lb.CssClass = MY_CLASS; // not selected
You can quickly get into trouble when defining inline styles, in that they're difficult to overwrite.
EDIT 2:
Something like this code should work. You may have to loop through all the LinkButtons in the list, but I don't think so. I'd just turn off ViewState on the LinkButtons.
// container for links. so you can reference them
// outside of the creation method if you wish. I'd probably call this method in the
// Page_Init Event.
List<LinkButton> listOfLinks = new List<LinkButton>();
const string MY_LB_CLASS = "linkButton"; // generic lb class
private void createSomeLinks() {
for (int i = 0; i < 10; i++) {
// create 10 links.
LinkButton lb = new LinkButton()
{
ID = "lb" + i,
CssClass = MY_LB_CLASS
};
lb.Click += new EventHandler(lb_Click); // Add the click event
}
// You can bind the List of LinkButtons here, or do something with them.
}
void lb_Click(Object sender, EventArgs e) {
LinkButton lb = sender as LinkButton; // cast the sender as LinkButton
if (lb != null) {
// Make the link you clicked selected.
lb.CssClass = MY_LB_CLASS + " selected";
}
}
Try lb.Style.Remove("font-weight"). I didn't test it, but you can try it out.
Alternatively, have you tried settings the Font.Bold property?
lb.Font.Bold = true;
Try ListBox1.Attributes.Add("style","font-weight:bold");
and ListBox1.Attributes.Add("style","font-weight:normal");
or even better is
// css
.active {font-weight:bold}
.notactive {font-weight:normal}
//c#
ListBox1.CssClass = "active";
ListBox1.CssClass = "notactive ";
you could try lb.Style.Remove("font-weight");
set the font bold in the click event of the link button and set the enable view state property to false in the click event itself which will reset the link to the normal foam in the other click

Categories

Resources