I tried to add an Apply button to my Options form but it wouldn't work.
Here's what I've tried:
in frm_Main
frm_Options Options = new frm_Options();
Options.btn_Apply.Click += new System.EventHandler(this.btn_Apply_Click);
Later...
Options.Show();
...
void btn_Apply_Click(object sender, EventArgs e)
{
LoadPreferences();
}
Basically the only way I could think of doing it was to add an even handler from frm_Main to the button in frm_Options. My guess is you can't do this, is there another way or is it possible the way I tried to do it?
Edit1:
I want to do this in frm_Main because I want the button, when pressed, to call a function in frm_Main
And by "doesn't work" I mean the event doesn't fire when the "Apply" button is clicked
You need to declare your event within the options form
public event EventHandler RefreshOptions;
and in the button click event raise the event (if it has a subscriber) - e.g.
var refreshOptions = RefreshOptions;
if (refreshOptions != null)
refreshOptions(this, new EventArgs());
Then subscribe to the event in your main form -
Options options = new Options();
options.RefreshOptions += MainRefresh;
and create the MainRefresh event (or whatever you call it)
void MainRefresh(object sender, EventArgs e)
{
// TODO
}
Related
I have a problem with User form Click that I am trying to make in C# using a usercontrol.
It consists of a picturebox and a label. I want to call the click event but the picturebox and the label don't do anything when I click them. Only the background area of the usercontrol does what I want it to do. Any ideas?
here's my code
for (int i = 0; i < listitems2.Length; i++)
{
listitems2[i] = new declined();
//adding sample data to each dynamic user
listitems2[i].dicon = dicon[i];
listitems2[i].did = did[i];
listitems2[i].dname = dname[i];
//adding data to flow layout panel
flowLayoutPanel2.Controls.Add(listitems2[i]);
// below line will assing this (usercontrolclick) event to every user control created dynamically
listitems2[i].Click += new System.EventHandler(this.UserControl_Click);
}
for click function
void UserControl_Click(object sender, EventArgs e)
{
string ctrlName = ((UserControl)sender).Name;
applicable obj = (applicable)sender;
studid.Text = obj.id;
studname.Text = obj.name;
pictureBox1.Image = obj.icon;
}
You added OnClick handler to your UserControl, so only clicks made on UserControl will be registered. To enable Click event for all the controls on your form, you need to add your click handler to all other controls.
But, according to your code, you're adding click handling on form where your control is located. In this case, you cannot register clicks on control from "outside" (you can by making Label and PictureBox controls public and adding handlers for their OnClick events but that is wrong way to do it)
My suggestion is to make custom event on your form and raise it on Form, Label and PictureBox click, and then make handler for that event on form which holds your UserControl.
Something like this:
//make custom eventHandler on your UserControl
[Browsable(true)]
public event EventHandler UserControlClicked;
//constructor
public UserControl1()
{
InitializeComponent();
//after intialize compoment add same handler for all three controls
this.Click += ControlClicked;
this.pictureBox1.Click += ControlClicked;
this.label1.Click += ControlClicked;
}
//this method will "catch" all clicks
private void ControlClicked(object sender, EventArgs e)
{
//raise event
UserControlClicked?.Invoke(this, e);
}
and on form where your custom control is, add handler for UserControlClicked (maybe with cast, I don't know what listItems2[i] contains):
listitems2[i].UserControlClicked+= new System.EventHandler(this.UserControl_Click);
or maybe like this (with casting)
(listitems2[i] as UserControl1).UserControlClicked+= new System.EventHandler(this.UserControl_Click);
and handle the rest in your UserControl_Click method like before
I am trying to change a buttons visible status with a checkbox that is on another form for example;
when the checkbox checked state changes on form 2 than the visible property for button 1 on form1 changes. If someone could point me in the right direction i would appropriate it thank you.
Define event on Form2. E.g.
public event EventHandler StateChanged;
Raise this event when checkbox checked state changes:
private void Checkbox_CheckedChanged(object sender, EventArgs e)
{
if (StateChanged != null)
StateChanged(this, EventArgs.Empty);
}
Subscribe to this event in Form1
form2.StateChanged += Form2_StateChanged;
Change a button in this event handler:
private void Form2_StateChanged(object sender, EventArgs e)
{
button.Visible = !button.Visible;
}
Normally when I do something like this I add a method that calls it.
Form1 with the button
public void SetVisibility(bool visible)
{
Button.Visible = visible;
}
Form 2 With CheckBox
CheckBox_CheckChanged(object sender, EventArgs e)
{
Form1.SetVisibility(CheckBox.Checked);
}
Adding a public method on your form also enables you to control it from others forms. Not sure what the best answer is, thats up to you.
EDIT:
Not related to the question but...
On Form 2
var form1Control = new Form1();
form1Control.SetVisibility(true);
On form1, I have registerButton that create new registerForm with an acceptButton on it. Both dynamically created:
private void registerButton_Click(object sender, EventArgs e)
{
registerButton.Enabled = false;
Form registrationForm = new Form();
registrationForm.Text = "Register new account";
registrationForm.Visible = true;
Button createButton = new Button();
createButton.Text = "Accept";
registrationForm.Controls.Add(createButton);
createButton.Click+= new EventHandler(createButton_Click);
}
How can I close registerForm after clicking acceptButton without closing the form1?
You've lost the reference to the registration form instance. But you can always get it back from the sender argument that's passed to the Click event handler. Like this:
private void registrationButton_Click(object sender, EventArgs e) {
var btn = (Control)sender;
btn.FindForm().Close();
}
For your code (which I don't recommend to use) fix will be
createButton.Click += (s,e) => registrationForm.Close();
When you attach this lambda as event handler, you have opportunity to capture registrationForm instance in a closure. Thus form instance will be available when click event will happen, and you will be able to close this form.
Better approach: instead of adding button dynamically to form, place this button statically in designer and attach click event handler which will close the form:
private void acceptButton_Click(object sender, EventArgs e)
{
Close();
}
Usage of registration form will be simple as:
private void registerButton_Click(object sender, EventArgs e)
{
Form registrationForm = new Form();
registrationForm.Show();
}
Add this.Close() at the click event of acceptButton.
You can attach an event to it dynamically. While creating the button, do acceptButton.Click += new System.EventHandler(accepButton_click); and create matching function or press Tab twice after doing the +=.
I just started programming, and I want to use WinForms to make multiple buttons that you can click on to change from white to lime-green and back to white. I have done this for one button:
private void button1_Click(object sender, EventArgs e)
{
if (button1.BackColor != Color.Lime)
{
button1.BackColor = Color.Lime;
}
else
{
button1.BackColor = Color.White;
}
}
Now I could copy and paste that for all of the buttons, but I know that is inefficient; and if I use winforms to reference button1 on button2, it will just change the color of button1 (obviously).
So, do I need to use a helper method, new class, or something else? What would that look like?
There are a couple of approaches. One might be to create a common function which the different buttons call:
private void button1_Click(object sender, EventArgs e)
{
ChangeColor(button1);
}
private void ChangeColor(Button button)
{
if (button.BackColor != Color.Lime)
button.BackColor = Color.Lime;
else
button.BackColor = Color.White;
}
Then each button handler can use that same function call.
Or, if all of these buttons will always ever do exactly the same thing, then you can use one click handler function for all of them. In this case what you'd need to do is determine which button invoked the handler (whereas you're currently referencing button1 directly) so that you know which one to change. The sender object passed into the handler function is actually a reference to the form element which invoked the handler. All you need to do is cast it:
private void button_Click(object sender, EventArgs e)
{
var button = (Button)sender;
if (button.BackColor != Color.Lime)
button.BackColor = Color.Lime;
else
button.BackColor = Color.White;
}
So first the handler grabs a reference to the button which invoked it, then runs the logic on that button. Note also how I made the name of the handler function slightly more generic. Now you'd go to the form designer and set button_Click as the click handler for all of the buttons which should invoke this.
You do this the exact same way you'd do it for any C# class. You derive your own class and customize the base class behavior. Every event has a corresponding OnXxxx() method that you can override.
Add a new class to your project and paste this code:
using System;
using System.Windows.Forms;
class MyButton : Button {
protected override void OnClick(EventArgs e) {
// Your code here
//...
base.OnClick(e);
}
}
Change the code in OnClick() to do what you want to do. Compile. You'll now have your own button control on the top of the toolbox. And can drop as many copies of it as you want on a form. They'll all behave the same without having to add any code in the form.
Probably the easiest way would be to have each button invoke the same click handler. Then inside of your handler use the Sender instead of hard coding Button1.
private void buttons_Click(object sender, EventArgs e)
{
var theButton = (Button) sender;
if (theButton.BackColor != Color.Lime)
{
theButton.BackColor = Color.Lime;
}
else
{
theButton.BackColor = Color.White;
}
}
You can get the button that raised the Click event by casting sender to Button.
You can then add the same handler to every button.
I'm a VB guy.... in VB.Net you can add multiple handlers for events and connect multiple events to the same handler.
This sub hooks all clicks to color the buttons.
Private Sub ColorButtons(sender As System.Object, e As System.EventArgs) _
Handles Button1.Click, Button2.Click, ..
I do this all the time accidentally because I drag/copy a control to make a new one and the new button gets added to the original's events.
Other Subs can handle the same events to do other work - both will execute.
No idea how to do this in C#.
The proper way to do this really is to associate each button's click event to the function you have coded for that purpose (you want the function to run when the button is clicked, right?), so add the following (or similar) to an appropriate section of your code:
MyButton1.Click += new RoutedEventHandler(buttons_Click);
MyButton2.Click += new RoutedEventHandler(buttons_Click);
etc...
You can associate as many controls to the event handler as you like.
What I usually do before is this:
private void button2_Click(object sender, EventArgs e)
{
button1.PerformClick();
}
This code will just simply run the codes under button1_Click.
But try not to practice as such and just simply put it in a function/method just like what David suggested.
I have a Main page that contains a listBox.
When a user selects a profile form the list box, this opens up a child window called pWindow.
This window as the option to delete the current profile via a hyperlink button that opens up a another confirmation window called dprofile.
My question being is it possible that once a user has confirmed to delete the current profile they are in, and confirmed it in the button click on dProfile, how can I update the listBox in the first Main page so that the list no longer contains the deleted profile (which it is not doing at present.
In the dProfile window I have created an event -
public event EventHandler SubmitClicked;
Where in the OK button click I have-
private void OKButton_Click(object sender, RoutedEventArgs e)
{
if (SubmitClicked != null)
{
SubmitClicked(this, new EventArgs());
}
}
So on the Main page I have added-
private void deleteProfile_SubmitClicked(object sender, EventArgs e)
{
WebService.Service1SoapClient client = new WebService.Service1SoapClient();
listBox1.Items.Clear();
client.profileListCompleted += new EventHandler<profileListCompletedEventArgs>(client_profileListCompleted);
client.profileListAsync(ID);
}
I thought this may have updated the listBox as it was confirmed in the dProfile form however when the form closes, the listBox stays the same and I have to manually refresh the webpage to see the update. How can I do this?
If I understood it correctly then you have three pages. Main, pWindow and dProfile. Earlier you were trying to close pWindwow from dProfile and that was working properly. Now you want to refresh the listBox1 on Main Page.
To achieve that you may follow a similar strategy. You are probably opening pWindow from Main page with something on the following line
pWindow pWin = new pWindow();
pWin.Show();
Now you may define a new event in pWindow class.
public event EventHandler pWindowRefeshListBox;
Then in your event handler for deleteProfile_SubmitClicked you may raise the event to refresh listbox1, something on the following line:
private void deleteProfile_SubmitClicked(object sender, EventArgs e)
{
if(pWindowRefreshListBox != null)
pWindowRefreshListBox(this, new EventArgs());
this.Close();
}
Then in your main page register the event against pWin object, which you defined earlier.
pWin.pWindowRefreshListBox += new new EventHandler(pWindow_pWindowRefreshListBox);
Then define the event in Main page.
private void pWindow_pWindowRefreshListBox(object sender, EventArgs e)
{
listBox1.Items.Clear();
}
This should refresh the listbox. I haven't test the code or the syntax. So you may check it
before implementing.
EDIT
you may define the event in dProfile as static
public static event EventHandler SubmitClicked;
Then you will be able to register it in Main and pWindow against Class Name
dProfile.SubmitClicked += new ..............
Then implement it accordingly, in pWindow, close the window and in main refresh listbox
EDIT:
You may create instance of deleteProfile on the main page register the following in your main
deleteProfile.SubmitClicked += new EventHandler(deleteProfile _SubmitClicked)
this should work