Cancel events from a legacy form - c#

I have a main form that has buttons, the role of one of them in disabling all controls of the form in general.
I also have a child form that inherits the buttons and the actions of them, as I could prevent the events of the parent form at a certain point from running that is, temporarily remove the event, for example if the user has a text and does not fill it out and gives the button I do not want anything to be disabled
I think there is a way in c# that like the "eventname"=- I don't remember well
This is an example of my base or parent form, with a button that does actions
Parent Form
namespace WindowsFormsApp1
{
public partial class BaseMantenimiento1 : DevExpress.XtraEditors.XtraForm
{
public BaseMantenimiento1()
{
InitializeComponent();
}
private void BaseMantenimiento1_Load(object sender, EventArgs e)
{
Guardar.Enabled = false;
Cancelar.Enabled = false;
controles.habilitarcontroles(false, xtraTabControl1);
}
private void Nuevo_Click(object sender, EventArgs e)
{
Guardar.Enabled = true;
Cancelar.Enabled = true;
Editar.Enabled = false;
Buscar.Enabled = false;
Nuevo.Enabled = false;
controles.habilitarcontroles(true, xtraTabControl1);
}
This is my child form with its basic code
child form
public partial class Mantenimiento_Empresas : BaseMantenimiento1
{
public Mantenimiento_Empresas()
{
InitializeComponent();
}
What I wanted was that if in the child form I gave the button save, but they did not fill the textbox well, then the event that this inherits from its parent form is not executed, so I took the event and then below if everything is fine I trigger the event of the parent with
base.Save_Click(null, null);

I found what I was looking for, in the same space where the components are initialized I must place the following
public Mantenimineto_Bicicletas()
{
InitializeComponent();
Save.Click -= base.Save_Click;
}

Related

Calling mehtod from another form / user control nothing is happening while on parent form its working

I have a parent form that loads different user controls but when I am trying to access a method on the parent form from a button on the user controller which is not working but if the same method is accessed from the own parent form its all good I excluded the rest of code and here is the code not working
method on Parent Form:
using IT_HUB_MANAGEMENT_SOLUTION.SERVICES;
namespace IT_HUB_MANAGEMENT_SOLUTION.APP_FORMS
{
public partial class FIRST_RUN_FRM : Form
{
public FIRST_RUN_FRM()
{
InitializeComponent();
}
public void NEXT_STEP_CMD()
{
MAIN_PANEL.Controls.Clear();
FIRST_RUN_OBJECTS.CRYSTAL_REPORTS_CONTROL cRYSTAL_REPORTS_CONTROL = new();
cRYSTAL_REPORTS_CONTROL.Dock = DockStyle.Fill;
MAIN_PANEL.Controls.Add(cRYSTAL_REPORTS_CONTROL);
}
}
here is the code on user controls:
public partial class DOTNET_INSTALLER_CONTROL : UserControl
{
public DOTNET_INSTALLER_CONTROL()
{
InitializeComponent();
}
private void NEXT_BTN_Click(object sender, EventArgs e)
{
FIRST_RUN_FRM fff = new();
fff.NEXT_STEP_CMD();
}
}
First of all, this is not a normal behavior (at least for me) that a UserControl calls a parent form method directly. Usually user controls are not aware of the parent that is using them, and for me, it's a really smelly code.
In your code:
public partial class DOTNET_INSTALLER_CONTROL : UserControl
{
public DOTNET_INSTALLER_CONTROL()
{
InitializeComponent();
}
private void NEXT_BTN_Click(object sender, EventArgs e)
{
FIRST_RUN_FRM fff = new();
fff.NEXT_STEP_CMD();
}
}
You're simply creating a new instance of the FIRST_RUN_FORM (Also try to follow the naming convention) and then calling it's function. This won't throw a compiler error since it's a valid .Net syntax. You're creating a new class and calling a public function inside it. However, it won't show anything on your initial form because it's not the same instance.
There's two ways to fix this code, and I don't like the first way I'll show you.
You can add the parent form instance to the user control and pass it on when creating a new instance of the UC. Something like this:
public partial class DOTNET_INSTALLER_CONTROL : UserControl
{
private FIRST_RUN_FRM _parent = null;
public DOTNET_INSTALLER_CONTROL(FIRST_RUN_FRM parent)
{
InitializeComponent();
_parent = parent;
}
private void NEXT_BTN_Click(object sender, EventArgs e)
{
if (_parent == null)
{
return;
}
_parent.NEXT_STEP_CMD(); //This might throw an error not related to this question
}
}
I wouldn't recommend this though.
What I'd go for is using events, this way you don't need the UserControl to know who their parent is or what should be done to the parent when a button inside the UC is clicked.
Event:
In the user control:
public partial class DOTNET_INSTALLER_CONTROL : UserControl
{
public event EventHandler NextButtonClicked;
public DOTNET_INSTALLER_CONTROL(FIRST_RUN_FRM parent)
{
InitializeComponent();
_parent = parent;
}
private void NEXT_BTN_Click(object sender, EventArgs e)
{
OnNextButtonClicked();
}
protected virtual void OnNextButtonClicked()
{
EventHandler handler = NextButtonClicked;
handler?.Invoke(this, null);
}
}
And in the parent form you'll subscribe to this event and react when it's fired.

calling button click function from another class

i currently have one form and a few user control, i have a panel set from the Form1 - mainpanel, so that whenever i click a button, one of the user control will be showing on the mainPanel.
my problem is that one of the control(InfoSetting) has some other new buttons, and when i click it I would like the mainPanel to show the new user control. However, right now all other buttons from Form1 is working fine, but when I click on the InfoSetting button, nothing seems to show up.
here is my code from Form1
public partial class Form1 : MetroFramework.Forms.MetroForm
{
InfoSettings infoSetting;
CashSales cashSales;
PriceSetting priceSetting;
public Form1()
{
InitializeComponent();
infoSetting = new InfoSettings();
cashSales = new CashSales();
priceSetting = new PriceSetting();
}
protected void ButtonClicked(object sender, EventArgs e)
{
buttonHandler(sender);
}
public void buttonHandler(object sender)
{
Button button = sender as Button;
mainPanel.Controls.Clear();
if (button != null)
{
switch (button.Name)
{
case "HomeBtn":
infoSetting.Dock = DockStyle.Fill;
mainPanel.Controls.Add(infoSetting);
break;
case "cashSalesBtn":
cashSales.Dock = DockStyle.Fill;
mainPanel.Controls.Add(cashSales);
break;
case "settingBtn":
infoSetting.Dock = DockStyle.Fill;
mainPanel.Controls.Add(infoSetting);
break;
case "priceSettingBtn":
cashSales.Dock = DockStyle.Fill;
mainPanel.Controls.Add(cashSales);
break;
default:
mainPanel.Controls.Clear();
break;
}
}
}
and here is the code from the InfoSetting user control
public partial class InfoSettings : UserControl
{
public InfoSettings()
{
InitializeComponent();
}
private void priceSettingBtn_Click(object sender, EventArgs e)
{
Form1 form1 = new Form1();
form1.buttonHandler(sender);
}
}
as stuartd said you can add a call to your parent Form:
public partial class InfoSettings : UserControl
{
public InfoSettings()
{
InitializeComponent();
}
private void settingBtn_Click(object sender, EventArgs e)
{
Form1 form1 = (Form1) this.Parent;
form1.buttonHandler(sender);
}
}
It would probably be better to have a common class that you can access in both form and user control and have the code you want to run in a method there. Something like:
public class FormHelper
{
public void CodeIWantToRunIn2Places()
{
// Implementation Here
}
}
You can implement the above as a singleton so you have access in both places. Then in your form classes you could do:
FormHelper.Instance.CodeIWantToRunIn2Places();
In your event handler as well as in your user control.
You can make the Form 1 as "static" and also the method buttonHandler(object sender) as "static" as well.
Then inside the priceSettingBtn_Click, call the below function directly
Form1.buttonHandler(sender);
I would have a global object with a pointer to all the forms in the application.
public Global
{
public Form1 MainForm;
public Dialog1 D1;
...
}
public static Global = new Global();
In as each form is created
Global.MainForm = form1;
then you can go
private void priceSettingBtn_Click(object sender, EventArgs e)
{
Global.MainForm.buttonHandler(sender);
}
As other have said , its probably better to not call the click handler, its better to have this code and the real click handler call a business logic level function

Form Closing Event visual studio c#

Straight to the problem:
In my main form, i have a three buttons that open three different forms. I will show you how it is built.
MainForm (Here is three buttons, with the three different form names on them)
Theory -> Click this button to open TheoryForm
Tasks -> Click this button to open TasksForm
Compete -> Click this button to open CompeteForm
Inside my TasksForm is a button that is going to open the TheoryForm. Here is my code:
public partial class TasksForm : Form
{
public TasksForm()
{
InitializeComponent();
}
public void TheoryButton_Click(object sender, EventArgs e)
{
Form TheoryForm_Child = new TeoriForm();
TheoryForm_Child.Show();
}
//Add some code here so that when `TasksForm` closes, the `TheoryForm_Child` closes too.
}
And what I can't figure out is, when the TasksForm is closed, the TheoryForm is supposed to close as well, right now it doesn't.
Try declaring the variable to your TheoryForm outside of the TheoryButton.Click event handler and then use it in your TaskForm.FormClosing event handler to close it.
public partial class TasksForm : Form
{
private Form TheoryForm_Child;
public TasksForm()
{
InitializeComponent();
FormClosing += TaskForm_FormClosing;
}
public void TheoryButton_Click(object sender, EventArgs e)
{
TheoryForm_Child = new TeoriForm();
TheoryForm_Child.Show();
}
public void TaskForm_FormClosing(object sender, FormClosingEventArgs e)
{
if(TheoryForm_Child != null)
TheoryForm_Child.Close();
}
}
Just because TasksForm is creating TheoryForm does not mean that when TasksForm is closed, so will TheoryForm. Instead, you should close it explicitly like by handing the closed event in your TasksForm, like this.
public partial class TasksForm : Form
{
Form _TheoryFor_Child = new TheoryForm();
public TasksForm()
{
InitializeComponent();
Closed += TasksForm_Closed;
}
private void TasksForm_Closed(object sender, EventArgs e)
{
_TheoryFor_Child.Close();
}
private void TheoryButton_Click(object sender, EventArgs e)
{
_TheoryFor_Child.Show();
}
}
You need to connect parent and child form in some way.
For example in giving the child form the parent form as owner.
Simply call
TheoryForm_Child.Show(this);
There is a really simple solution. You should use the other version of Show method like this:
Form TheoryForm_Child = new TeoriForm();
TheoryForm_Child.Show(this);
That's all. Then your form will be owner of theory form. So it will automagically destroy Theory form after closing itself.
More reading here: https://msdn.microsoft.com/en-us/library/szcefbbd%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396

Showing child using user control in wpf

Reuirement :
Need to show all child pages in a master layout. Without opening as new window i mean it should not be visible as separate window from main window
Solution i figured :
I used content presenter in main page.
Create all other pages as User controls.
On click of menu ViewWindow.Content = new SalesEntry();
By using that i am showing that.
Problem :
To close that user control i used a button click (button present inside the user control)
to preform this.Visibility = Visibility.Hidden;
But every time when user request this page the page is initialized and shown.
So, whats the best approach for this to overcome or any other way to solve this.
(I was told not to use any framework as a project requirement)
I am very new WPF..
Please help me in this..
What you are doing is fine, I don't really understand the problem here but I will tell you how I would do it.
You will have a parent view, a Window. You will have many childs, UserControl's.
Inside your window, you should have a way of selecting which child to show. This can be done using buttons or a menu.
When you select a child, you instantiate it as an object and subscribe to its exit event. When this event is fired by the child, you remove that child from your childs in the parent window.
// This one defines the signature of your exit event handler
public delegate void OnExitHandler(UserControl sender);
// This is your child, UserControl
public partial class MyChild : UserControl
{
public event OnExitHandler OnExit;
public MyChild()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
this.OnExit(this);
}
}
// This is your parent, Window
public partial class MainWindow : Window
{
private MyChild _control; // You can have a List<UserControl> for multiple
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
_control = new MyChild();
_control.OnExit += _control_OnExit; // Subscribe to event so you can remove the child when it exits
_content.Content = _control; // _content is a ContentControl defined in Window.xaml
}
private void _control_OnExit(UserControl sender)
{
if(sender == _control)
{
// Or if you have a collection remove the sender like
// _controls.Remove(sender);
_control = null;
_content.Content = null;
}
}
}
If your problem is something else, please comment.

Show/Hide one User Control from another

I am tinkering around with User Controls and I've found myself stumped. My form has 2 User Controls, a TitleScreen and a MainScreen. I need for the TitleScreen to be visible when the program runs and then invisible when the "new game" button is clicked, at which point the MainScreen needs to be visible. Unfortunately, I can't figure out how to do this.
FormMain.cs
#region Property Region
public UserControls.MainScreen ControlMainScreen
{
get { return controlMainScreen; }
}
#endregion
#region Constructor Region
public FormMain()
{
InitializeComponent();
controlMainScreen.Visible = false;
}
#endregion
TitleScreen.cs
public void btnNewGame_Click(object sender, EventArgs e)
{
this.Visible = false;
FormMain.ControlMainScreen.Visible = true;
}
Obviously it doesn't work, but I've tried everything that I know how to do. I also have no clue how to make controlMainScreen static since I didn't actually make the declaration (VS did). Any help would be appreciated.
You could use ParentForm which is a property on UserControl to get a reference to the parent form.
((YourFormsExactType)(this.ParentForm)).ControlMainScreen.Visible = false;
Add a user control on the Win project and then dynamically add to the Form.
Here is the code:
public Show_hideControl()
{
InitializeComponent();
//Adding First User control
Main _main = new Main();
panel1.Controls.Add(_main);
}
private void button1_Click(object sender, EventArgs e)
{
//removing already added user control
panel1.Controls.Clear();
//Adding second user control
Alternative _alter = new Alternative();
panel1.Controls.Add(_alter);
}

Categories

Resources