I have just created a program with that code:
class INF2 : Form1
{
public void checkBox1_CheckedChanged(object sender, EventArgs e)
{
Zaznacz();
}
private void Zaznacz()
{
if (checkBox1.Checked == true)
{
MessageBox.Show("Dot Net Perls is awesome.");
}
}
}
where the function inherits from:
public void checkBox1_CheckedChanged(object sender, EventArgs e)
{
}
inside the Form1 ( it's a normal checkBox) and I want to see a messagebox when I press the checkbox by the INF2 class (necessarily inheritance)
Read your compiler warnings.
You created a new method that happens to have the same name as the base method, but doesn't actually have anything to do with it.
You need to use virtual and override.
Related
I am building a simple web browser in C#. In order to have all of my buttons such as the go, forward, back, refresh button, along with textbox input in a single tab, I have decided to put a tool strip and web browser control in a single user control that I created. This will enable me to just drop 1 control into a tab. Unfortunately when I try to use my user control it does not work. I know that my code inside the user control is fine, because when I had it in my main form, it functioned properly. I think the main piece that I am missing is I do not understand how to properly call the user control from the main form. Can someone guide me in the right direction here?
The main form.
namespace WebBrowser.UI
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
MessageBox.Show("random text.");
}
}
}
And the User Control
namespace WebBrowser.UI
{
public partial class adkinsBrowser : UserControl
{
public adkinsBrowser()
{
InitializeComponent();
}
private void toolStripTextBox1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
webBrowser1.Navigate(toolStripTextBox1.Text.ToString());
}
}
private void toolStripTextBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
e.SuppressKeyPress = true;
}
}
private void toolStripButton5_Click(object sender, EventArgs e)
{
webBrowser1.Navigate(toolStripTextBox1.Text.ToString());
}
}
}
I've created a new form, in which I have a toolbox. When I press a button in that form, it should relay that information that has been entered by the user(toolboxbox value) to the main form, in which it should say that piece of information in a label.
Since the method to create that username from the toolbox is private, I cannot access it from any other way. Making it public does not seem to make a difference, neither does get,set (from the way I've been trying to atleast).
Picture that may help explaining it:
Code (in which to create user):
namespace WindowsFormsApplication3
{
public partial class Newuserform : Form
{
public Newuserform()
{
InitializeComponent();
}
private void buttonCreateUser_Click(object sender, EventArgs e)
{
string uname = textboxUsername.ToString();
}
public void Unamecreate()
{
}
}
}
Form1 Code (To receive created user):
namespace WindowsFormsApplication3
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void aboutToolStripMenuItem1_Click(object sender, EventArgs e)
{
Aboutform form2 = new Aboutform();
form2.Show();
}
private void newLocalUserToolStripMenuItem_Click(object sender, EventArgs e)
{
Newuserform formnewuser = new Newuserform();
formnewuser.Show();
}
}
}
you have a lot of options.
One way is to create an event and handle it in the main form.
public partial class Newuserform : Form
{
//the public property
public event EventHandler<string> UnameChanged;
public Newuserform()
{
InitializeComponent();
}
private void buttonCreateUser_Click(object sender, EventArgs e)
{
if (UnameChanged != null)
UnameChanged(textboxUsername.ToString()); //fire the event
}
}
Now, to "handle" the event, do the following in your main form:
private void newLocalUserToolStripMenuItem_Click(object sender, EventArgs e)
{
Newuserform formnewuser = new Newuserform();
formnewuser.UnameChanged += Handler;
formnewuser.Show();
}
private void Handler (object sender, string Uname)
{
// do something wit the new Uname.
}
note: recreating the Newuserform will require to cleanup previous attached resources.
I have a form with multiple instances of a user control on it.
I've assigned the following:
Switch.armySwitchCloseButton.Click += armySwitchClose;
So when one of those instances is pressed, I call the following method:
void armySwitchClose(object sender, EventArgs e)
The above method has a bunch of additional code in it which isn't required for here.
Now what I need to do is from another button, call this above function from every instance.
How can I do this?
Many Thanks
In constructor of each user control you can pass the same instance of some object who knows how to run this method
void armySwitchClose(object sender, EventArgs e)
Then, you call this method inside each event method, for ex:
Public Class UserControl(){
private MakeEvent makeEvent;
Public MyClass(MakeEvent makeEvent)
{
this.makeEvent = makeEvent;
Switch.armySwitchCloseButton.Click += armySwitchClose;
}
void armySwitchClose(object sender, EventArgs e)
{
makeEvent.armySwitchClose(sender,e);
}
}
Public Class MakeEvent() {
void armySwitchClose(object sender, EventArgs e)
{
//the real implementation
}
}
Hope this solve your problem.
Oh, I think I get your problem wrong... When you click in one button all the other events in others UC must be triggered, right? This problem can be solved with the Observer Pattern
Public Interface IObserver
{
void armySwitchClose(object sender, EventArgs e);
}
Public UserControl1: Observer
{
void armySwitchClose(object sender, EventArgs e)
{
//implementation UC1
}
}
Public UserControl2: Observer
{
void armySwitchClose(object sender, EventArgs e)
{
//implementation UC2
}
}
In button UC:
Public UserControlButton
{
private List<IObserver> observers;
public void addObserver(IObserver observer)
{
observers.Add(observer);
}
public void button_clickedEvent(object sender, EventArgs e)
{
foreach(IObserver observer in observers)
{
observer.armySwitchClose(object sender, EventArgs e);
}
}
}
In form with all buttons you call addObserver adding each user control.
I made a class so when the user selects item from listbox it uninstalls that item, except the problem is I can't access the list box. I tried public aswell, but in the code of form1.cs the only thing clostest to that list box is
keep in mind name of listbox is ProgramslistBox
Ok guys I re edited this post;
private void button1_Click(object sender, EventArgs e)
{
if(ProgramsListbox.SelectedIndex == -1)
{
MessageBox.Show("Please select an item to uninstall!");
}
else
{
ProgramsListbox_SelectedIndexChanged("",EventArgs.Empty);
}
}
this code is the FORM1.CS class, and I have another class called UninstallItem.cs is where I want my code to be, this below is my other class
namespace PC_TECH_Registery_Cleaner
{
class UninstallItem
{
public void uninstallSelectedItem()
{
Form1 c = new Form1();
}
}
}
And this below is still in my FORM1.CS class, I was experimenting with it :
public void ProgramsListbox_SelectedIndexChanged(object sender, EventArgs e)
{
//this will access the Uninstall item class so we can uninstall selected item.
UninstallItem c = new UninstallItem();
c.uninstallSelectedItem();
}
Within your Form1.cs create instance of UnIstallItem class and use it. Then on Button Click call "RemoveSelected" method of UnInstaItem class by passing programsListBox to it and it should remove the selected item.
public class Form1:Form
{
ListBox ProgramsListbox;
UninstallItem unistall;
public Form1(){
InitializeComponent();
uninstall = new UninstallItem();
button1.Click+= button1_Click;
}
void button1_Click(object sender, EventArgs e){
unistall.RemoveSelected(ProgramsListbox);
}
}
Then in your external class;
public class UninstallItem{
public UninstallItem{}
public void RemoveSelected(ListBox list)
{
if(list.SelectedIndex==-1)
{
MessageBox.Show("Please Select Item from List");
return;
}
list.Items.RemoveAt(list.SelectedIndex);
}
}
The 2 easy ways to think about this are either
Call the method in your class from the event handler in your form
Have a method on your class which matches the signature of an event handler, and subscribe to the event.
The first requires no major change
private MyClass myClass = new MyClass();
public void ProgramsListbox_SelectedIndexChanged(object sender, EventArgs e)
{
myClass.DoSomething();
}
The second requires your class to have a specific method that matches the signature of that event handler currently in your form
public class MyClass
{
public void DoSomething(object sender, EventArgs e)
{
var listBox = (ListBox)sender;
// read selected index perhaps, or selected item maybe
}
}
And then in your form
private MyClass myClass = new MyClass();
protected override void OnLoad(EventArgs e)
{
this.ProgramsListBox.SelectedIndexChanged += myClass.DoSomething;
}
I have done a base form for my window app but not sure is this correct or is there a better way to improve it.
My purpose:
Simplify my code at UI form
Create CRUD button to be inherited.
Question:
How do I implement interface with the 4 button events at the UserForm.cs by right clicking the UserForm:BaseForm. Currently I have to manually write all 4 button event to override.
My BaseForm seem to be empty. Can I put the messageBox.show("succcess") at my baseForm? Meaning to say that after run the UserForm.cs, it will run back to BaseForm. This can save up a few lines of code at userform.
Should I put my logger at the baseForm too?
My baseForm.cs
public BaseForm()
{
InitializeComponent();
}
public virtual void btnSave_Click(object sender, EventArgs e)
{
}
public virtual void btnDelete_Click(object sender, EventArgs e)
{
}
public virtual void btnNew_Click(object sender, EventArgs e)
{
}
public virtual void btnReset_Click(object sender, EventArgs e)
{
}
My UserForm.cs inherit baseForm
public override void btnSave_Click(object sender, EventArgs e)
{
if (!IsValidated()) return;
BindValueToObject();
try
{
user.Add();
bindingSource.Add(user);
MessageBox.Show("Success");
}
catch(Exception ex)
{
MessageBox.Show("failed");
Logger.Error(typeof(UserForm), ex.ToString());
return;
}
}
public override void btnDelete_Click(object sender, EventArgs e)
{
base.btnDelete_Click(sender, e);
}
public override void btnNew_Click(object sender, EventArgs e)
{
base.btnNew_Click(sender, e);
}
public override void btnReset_Click(object sender, EventArgs e)
{
base.btnReset_Click(sender, e);
}
1 - At the moment the methods in your base form is declared as virtual. This means that it is optional for any derived classes to override the methods. Therefore you won't be notified asking to override them. If this is your desired behavior then you will have to manually override the methods by either writing the code yourself or getting your IDE to generate the methods for you. However, if this is not the desired behavior and you would in fact like to force all derived classes to implement these methods, then you should declare them as abstract.
2 - Any calls to those methods will trigger the overridden methods in the derived class (if it exists) and thus the code in your base class will never get executed. If you're interested in both executing the code in the derived- and the base class then you should issue a call to the base method like this
public override void btnReset_Click(object sender, EventArgs e)
{
// do form specific stuff here
someButton.Text = String.Empty;
// then invoke base method
base.btnReset_Click(sender, e);
}
3 - If you're going to do general logging for the form, then putting it in the base class would be a good idea. However, remember always to invoke the base method call in any overridden method.