I want to get asp button ID from previous page and I'm getting an exception.
Here is my code for C#
public partial class ADD_MOBILE : System.Web.UI.Page
{
string BUTN_ID;
protected void Page_Load(object sender, EventArgs e)
{
Button button = (Button)sender;
string BUTTON_CLICKER_ID = button.ID;
BUTN_ID = BUTTON_CLICKER_ID;
}
protected void saveMOBILE_Click(object sender, EventArgs e)
{
if(BUTN_ID == "samsung"){ ... }
}
}
I'm getting exception at this point Button button = (Button)sender; why?
Okay, after going through your code it seems you want to get the button id so you can process some code based on that. Well, Let me make something clear, Page Load event will never give you the control that caused postback in sender object even if it gets triggered when you click a button and it posts back but it will NOT have the information in sender object for the control that posted it back.
For that you might want to use this approach from this James Johnson's answer to know which control caused postback:
/// <summary>
/// Retrieves the control that caused the postback.
/// </summary>
/// <param name="page"></param>
/// <returns></returns>
private Control GetControlThatCausedPostBack(Page page)
{
//initialize a control and set it to null
Control ctrl = null;
//get the event target name and find the control
string ctrlName = page.Request.Params.Get("__EVENTTARGET");
if (!String.IsNullOrEmpty(ctrlName))
ctrl = page.FindControl(ctrlName);
//return the control to the calling method
return ctrl;
}
This will return the Control object that you can further dig more into.
Otherwise, the suitable and neat approach in your case would be to do it like this:
public partial class ADD_MOBILE : System.Web.UI.Page
{
string BUTN_ID; // I do not think it is necessary here.
protected void Page_Load(object sender, EventArgs e)
{
}
protected void saveMOBILE_Click(object sender, EventArgs e)
{
Button button = (Button)sender;
if(button is null) return; // you can use == instead of keyword 'is'
if(button.ID.Equals("samsung"))
{
// DoStuff();
}
}
}
I hope you find it useful.
Related
I am trying to pass a simple string between pages but I don't know how to.
I created a test app where I click a button, the the value of "a" will pass on the next page (Page1.xaml.cs)
private void button1_Click(object sender, RoutedEventArgs e)
{
string a = "hello";
Page2 p2 = new Page2();
NavigationService.Navigate(p2, a);
}
Now, I want to extract the data from Page1 (Page2.xaml.cs)
private void NavigationService_LoadCompleted(object sender, NavigationEventArgs e)
{
string str = (string)e.ExtraData;
}
And then subscribing in the constructor (Page2.xaml.cs)
public Page2()
{
InitializeComponent();
NavigationService.LoadCompleted += NavigationService_LoadCompleted;
}
However when I ran the program I get an error. Can someone point out what am I missing?
Without a good Minimal, Complete, and Verifiable code example, it's impossible to know for sure everything that would be needed to address your question. However, if all you're asking is how to allow data to pass from one page to the next when navigating, it seems to me that the NavigationService.Navigate(object, object) overload would be useful for you.
The second parameter is the data you want to pass. The target page can handle the NavigationService.LoadCompleted event (or any other appropriate one you prefer), where the object value that was passed to the Navigate() method can be retrieved via the NavigationEventArgs.ExtraData property.
For example, in your first page:
private void button_Click(object sender, RoutedEventArgs e)
{
Page2 p2 = new Page2();
NavigationService.Navigate(p2, v.str);
}
then in your second page:
private void NavigationService_LoadCompleted(object sender, NavigationEventArgs e)
{
string str = (string)e.ExtraData;
// do whatever with str, like assign to a view model field, etc.
}
Of course, you'll subscribe the event handler, e.g. in your page's constructor or in XAML. For example:
public partial class Page2 : Page
{
public Page2()
{
InitializeComponent();
NavigationService.LoadCompleted += NavigationService_LoadCompleted;
}
private void button_Click(object sender, RoutedEventArgs e)
{
NavigationService.GoBack();
}
private void NavigationService_LoadCompleted(object sender, NavigationEventArgs e)
{
string str = (string)e.ExtraData;
// do whatever with str, like assign to a view model field, etc.
}
}
Instead of setting the textbox DataContext, set the entire page’s datacontext to some class ie the ViewModel for page1. Implement the interface INotifyPropertyChanged and ensure that in the set of the string property, the NotifyPropertyChanged(“ElementName”) is raised.
Now create a new view with a corresponding view model like this which should also implement the interface INotifyPropertyChanged. Create a textbox and bind it to a string property like in first page. Ensure TwoWay binding for both properties to ensure both target and source is updated while data is changed.
Create the instance of both viewModels in MainWindow. When user navigates to 2nd user control, set
Page2ViewModel.TextBoxString = Page1ViewModel.TextBoxString;
Like this do vice versa while navigating from Page2 to Page1.
Page1ViewModel.TextBoxString = Page2ViewModel.TextBoxString;
This way, both the textboxes will be updated during navigation.
This is just an overall idea. You need to learn more about MVVM and WPF from some tutorials. Search in google.
Here is my example, maybe it helps someone
in Page1.cs
examsStr = result.Content.ReadAsStringAsync().Result;
List<Exam> exams = JsonConvert.DeserializeObject<List<Exam>>(examsStr);
for (int i = 0; i < exams.Count; i++)
{
btnExam.Click += BtnExam_OptionsShow;
btnExam.DataContext = exams[i];
}
private void BtnExam_OptionsShow(object sender, EventArgs e)
{
ExamRead examPage = new ExamRead();
examPage.DataContext = ((sender as Button).DataContext as Exam);
this.NavigationService.Navigate(examPage);
}
in Page2.cs
this.Loaded += ExamRead_Loaded;
private void ExamRead_Loaded(object sender, RoutedEventArgs e)
{
examObj = (exam.DataContext as Exam);
(exam.Children[2] as Label).Content = examObj.ExamName + " - Exam Options";
}
Page2 has attribute Name="exam" and examObj is global variable in that Page2 class
I have 2 Asp button in a page (buttonUsername and buttonReset). First one perform an AD search, and set a private variable, while second button perform an action, using variable previously set.
public partial class ResetPassword : System.Web.UI.Page {
private UserPrincipal tmpPwdUser;
protected void buttonUsername_Click(object sender, EventArgs e) {
this.tmpPwdUser = ...
}
protected void buttonReset_Click(object sender, EventArgs e) {
myObj.myFunction(this.tmpPwdUser); // --> this.tmpPwdUser is void
}
}
My problem: this.tmpPwdUser is correctly set in buttonUsername_Click function, but when buttonReset_Click event is triggered, variable this.tmpPwdUser is null. I guess that when event is triggered, page is reloaded, so each local variable is reset. Is there a way to preserve state when button si clicked?
As you suspect, a new instance of the form is created for the new request. You have to preserve the value of the variable between those requests. One way to do this is to store the value in ViewState.
You can create a helper property that stores and retrieves the value from ViewState:
private UserPrincipal TmpPwdUser
{
get
{
return ViewState["UniqueViewStateKey"] As UserPrincipal;
}
set
{
ViewState["UniqueViewStateKey"] = value;
}
}
try using the OnEvent property instead of the onclick
Poperty on button ( OnCommand="Submit_Command")
in code behind
Submit_Command(object sender, CommandEventArgs e)
{
}
i have a textbox on .aspx page..On this page there is a user control .Inside this user contrl there is a button .I want o get the value of text box on button click which is not inside the user control .How can i do this
Please Help me .
write this line in you button click event of user control
protected void Button_Click(sender obj,EventArgs arg)
{
TextBox txtbox= (((MyPage)parent).FindControl("TextBoxid") as TextBox);
if(txtbox!=null)
(((MyPage)this.Page).FindControl("TextBoxid") as TextBox).Text;
//or
//(((MyPage)this.Parent).FindControl("TextBoxid") as TextBox).Text;
}
or
alternative is create the property in your page and access it in your user control
public string txtValue
{
get
{
return TextboxID.Text;
}
}
in button click event of user control
protected void Button_Click(sender obj,EventArgs arg)
{
string txtvalue = ((Mypage)this.Page).txtValue;
//or
//((MyPage)this.Parent).txtValue;
}
protected void MyButton_Click(object sender, EventArgs e)
{
string TextBoxValue;
TextBoxValue = MyTextBox.Text;
}
Is it what you want ?
Try use the following method,
((TextBox)USerControl.Parent.FindControl("txtbox")).Text
((TextBox)USerControl.Page.FindControl("txtbox")).Text
or
((YourPageType)USerControl.Page).TextBox.Text
With de-coupling in mind, I would recommend that if your user control needs to access information outside of it, then that information should passed in, not vice versa. The control shouldn't be responsible for where the information comes from, it just knows there is information. With this in mind, I would recommend bubbling the event to get the required information.
Event Bubbling
This will involve creating a new delegate, and then triggering it once the Button has been clicked, thus bubbling the event and allowing us to return the desired value, which in this case is the textbox value.
Step 1: Declare the delegate
// declare a delegate
public delegate string MyEventHandler(object sender, EventArgs e);
Step 2: Update the user control
// update the user control
public class MyUserControl : UserControl
{
// add the delegate property to your user control
public event MyEventHandler OnSomeButtonPressed;
// trigger the event when the button is pressed
protected void MyButton_Click(object sender, EventArgs e)
{
string someString = string.Empty;
if (this.OnSomeButtonPressed != null)
{
someString = this.OnSomeButtonPressed(this, e);
}
// do something with the string
}
}
Step 3: Update the page
// be sure to register the event in the page!
public class MyPage : Page
{
protected override void OnLoad(object sender, EventArgs e)
{
base.OnLoad(sender, e);
myUserControl.OnSomeButtonPressed += this.HandleUserControl_ButtonClick;
}
public string HandleUserControl_ButtonClick(object sender, EventArgs e)
{
return this.SomeTextBox.Text;
}
}
I am creating a dynamic button in a custom class, outside of the .aspx codebehind. The custom class creates a Table object and generates a column of Buttons within that table. Once generated, the Table is loaded into a placeholder control. Everything is functioning well except for this problem:
How do I programmatically assign a Button Object a 'Click' event within the custom class?
MyButton.Click += new EventHandler(MyButtonClick);
This results in: 'The name 'MyButtonClick' does not exist in the current context' error.
I know it doesn't exist in the current context, but once the aspx page is rendered, the codebehind will include a method to handle 'MyButtonClick'. I don't know how store a Click event method name into a Button object from a custom class and pass it off to the aspx codebehind to be rendered.
You have to define an event in your custom control. Fire that event on button click so that your .aspx can handle it.
EDIT: Same principles apply to a custom class.
Control Code-Behind:
public delegate void ButtonEventHandler();
public event ButtonEventHandler ButtonEvent;
protected void Button1_Click(object sender, EventArgs e)
{
ButtonEvent();
}
.ASPX Code Behind:
protected override void OnInit(System.EventArgs e)
{
control1.ButtonEvent+=
new Control1.ButtonEventHandler (whatever_ButtonEvent);
}
protected void whatever_ButtonEvent()
{
//do something
}
Let's take this concept and apply it to a user control that has a textbox and two buttons. The user control is placed within a Gridview. When my code runs the method in my event handler method is always null. I think has to do w/the fact the a button is is in a user control which is in the gridview.
Here is my user control code.
public partial class User_Controls_GridViewFilter : System.Web.UI.UserControl
{
public event EventHandler UserControlButtonClicked;
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
renderPage();
}
}
private void OnUserControlButtonClick()
{
if (UserControlButtonClicked != null)
{
UserControlButtonClicked();
}
}
protected void btnSearch_Click(object sender, EventArgs e)
{
OnUserControlButtonClick();
}
protected void btnReset_Click(object sender, EventArgs e)
{
OnUserControlButtonClick();
}
}
I register the control on the aspx page.
((User_Controls_GridViewFilter)gvMapLayer.HeaderRow.FindControl("FilterBox1")).UserControlButtonClicked
+= new ButtonEventHandler(User_Controls_GridViewFilter_UserControlButtonClicked);
On postback: How can I access ASP.NET controls in my code-behind file, which are added programmatically?
I am adding a CheckBox control to a Placeholder control:
PlaceHolder.Controls.Add(new CheckBox { ID = "findme" });
Controls added in the ASPX file are showing up fine in Request.Form.AllKeys except the ones I add programatically. What am I doing wrong?
Enabling the use of the ViewState on the controls does not help. If only it was that simple :)
You should recreate your dynamic control on postback:
protected override void OnInit(EventArgs e)
{
string dynamicControlId = "MyControl";
TextBox textBox = new TextBox {ID = dynamicControlId};
placeHolder.Controls.Add(textBox);
}
CheckBox findme = PlaceHolder.FindControl("findme");
Is that what you mean?
You will need to add the dynamically add the control during Page_Load to build the page up correctly each time. And then in your (i am assuming button click) you can use an extension method (if you are using 3.5) to find the dynamic control you added in the Page_Load
protected void Page_Load(object sender, EventArgs e)
{
PlaceHolder.Controls.Add(new CheckBox {ID = "findme"});
}
protected void Submit_OnClick(object sender, EventArgs e)
{
var checkBox = PlaceHolder.FindControlRecursive("findme") as CheckBox;
}
Extension Method found here
public static class ControlExtensions
{
/// <summary>
/// recursively finds a child control of the specified parent.
/// </summary>
/// <param name="control"></param>
/// <param name="id"></param>
/// <returns></returns>
public static Control FindControlRecursive(this Control control, string id)
{
if (control == null) return null;
//try to find the control at the current level
Control ctrl = control.FindControl(id);
if (ctrl == null)
{
//search the children
foreach (Control child in control.Controls)
{
ctrl = FindControlRecursive(child, id);
if (ctrl != null) break;
}
}
return ctrl;
}
}