How can you update Parent form from Child dialog? - c#

Similar to Notepad's method 'Find' where you can find a certain word and the main form will highlight the word while keeping the Find dialog box focused.
Here's where I'm at so far:
[Main.cs] (Windows Form)
private new Find FindForm;
private delegate void FindNextCallback(int s, int l);
private cmdFind_Click(object sender, EventArgs e)
{
FindForm = new Find(txtInput.Text);
FindForm.FindNext += new FindEventHandler(FoundNext);
FindForm.Show();
}
private void FoundNext(object sender, FindEventArgs e)
{
Invoke(new FindNextCallback(SelectFoundText), new object[] { e.Start, e.Length });
}
private void SelectFoundText(int s, int l) { txtInput.Select(s, l); }
[Find.cs] (Windows Form)
private static FindEventArgs FindArgs;
public event FindEventHandler FindNext;
private void cmdFindNext_Click(object sender, EventArgs e)
{
FindArgs = new FindEventArgs(startingPosition, selectionLength);
FindNext?.Invoke(null, FindArgs);
}
My problem is that whenever the user clicks "Find Next" the Main form doesn't do anything until I actually close the Find form or manually Main.Focus().
Also, fairly new with creating my own events so any tips on proper ways, cleaner ways, shorter ways to write my code would be most appreciated.

The TextBox in parent form is updating but it doesn't show its selected text as highlighted, You can set HideSelection property of text box to false to make it show selected text as highlighted always, even when the control doesn't have focus.
You can use this property to keep text highlighted in a text box
control while another form or a dialog box has focus, such as a
spelling checker dialog box.

Related

TextBox took back focus while other controls don't

I wanted to focus to a TextBox when I leave an other TextBox.
Let's say I have 3 textboxes. The focus is in the first one, and when I click into the second one, I want to put the focus into the last one instead.
I subscribed to the first textbox's Leave event and tried to focus to the third textbox like: third.Focus(). It gains focus for a moment but then the second one got it eventually (the one I clicked).
Strangely if I replace the second TextBox to a MaskedTextBox (or to any other control), the focus remains on the third one.
Pressing Tab does work though.
These are plain textboxes right from the toolbox.
What is the reason, how can I solve this?
Try to handle Enter event of the textBox2. (In properties window double click on Enter event)
//From Form1.Designer.cs
this.textBox2.Enter += new System.EventHandler(this.textBox2_Enter);
private void textBox2_Enter(object sender, EventArgs e)
{
textBox3.Focus();
}
EDIT:
This code looks very strange, but it works for me. According to this post HERE I use ActiveControl property instead of Focus() method. But behavior of TextBox is very strange because it try to be focused multiple times.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
foreach (Control control in Controls)
{
control.LostFocus += (s, e) => Console.WriteLine(control.Name + " LostFocus");
control.GotFocus += (s, e) =>
{
Console.WriteLine(control.Name + " GotFocus");
if (!requestedFocusToTextBox2) return;
ActiveControl = textBox2; //textBox2.Focus() doesn't work
requestedFocusToTextBox2 = false;
};
}
}
private bool requestedFocusToTextBox2;
private void textBox1_Leave(object sender, EventArgs e)
{
ActiveControl = textBox2;
requestedFocusToTextBox2 = true;
}
}

Show panel on click

please for a little help in displaying the panel at the click of a button, namely in my application I have a FormMenu in which the panelCentralForm is displayed when loading.
When I click on btnListOfActiveUser_Click I manage to open FormListStaff over panelCentralForm using this code:
private void btnListOfActiveUser_Click(object sender, EventArgs e)
{
FormListStaff formListStaff = new FormListStaff();
AddFormToPanel(formListStaff);
}
private void AddFormToPanel(object form)
{
if (this.panelCentralForm.Controls.Count > 0)
this.panelCentralForm.Controls.RemoveAt(0);
Form fh = form as Form;
fh.TopLevel = false;
fh.FormBorderStyle = FormBorderStyle.None;
fh.Dock = DockStyle.Fill;
this.panelCentralForm.Controls.Add(fh);
this.panelCentralForm.Tag = fh;
fh.Show();
}
my question is how can I in a similar way that now when I click on buttonDashboard to return to me the first view, ie the view from the Central Form panel (panelCentralForm).
private void buttonDashboard_Click(object sender, EventArgs e)
{
panelCentralForm.Visible = true; //something like this, p.s. this code doesn't just work as an example I wrote
}
the whole view belongs from FormMenu.cs
Thanks a lot to everyone for the help
my question is how can I in a similar way that now when I click on
buttonDashboard to return to me the first view
Just Clear() the panel, then add the label back in?
this.panelCentralForm.Controls.Clear();
this.panelCentralForm.Controls.Add(label1);
The label should still be accessible even though it was previously removed from the panel since it is declared at form level in your designer file.

Getting a control name/Displaying tooltip text

I am developing a form with multiple options that simulates a signup form, and I want to display some tips and descriptions in a RichTextBox located by the options when the user's mouse hover by it's GroupBoxes.
Since I am fairly new to programming, I don't know if getting all the controls names one by one is the optimal, so I want to grab the controls' names inside of the tabControl control that I am using to organize everything.
private void TabControl1_MouseHover(object sender, EventArgs e)
{
foreach(Control c in this.Controls)
{
string name = c.Name;
TooltipText(name);
}
}
And I also have a method where I will write the text that will be displayed in the RichTextBox.
private string TooltipText(string name)
{
if(name == "Name:")
{
return "blabla";
}
else
{
return "none";
}
}
I've tried a generic method to show a message box if the control was detected and, as I suspected, nothing showed up:
private void TooltipText(string name)
{
if(name == "LBL_Name")
{
MessageBox.Show("hey");
return;
}
}
How can I properly detect the Groupboxes or other types of Controls inside of the TabControl control, and also display the text in the box beside it?
You don't have to create your own Tool Tips. The .net WinForms provides a ToolTip class. https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.tooltip?view=netframework-4.8
I added 2 radio buttons to a group box in design view.
Try it and see.
private void Form1_Load(object sender, EventArgs e)
{
ToolTip tip = new ToolTip();
tip.AutoPopDelay = 5000;
tip.InitialDelay = 1000;
tip.ReshowDelay = 500;
tip.SetToolTip(radioButton1, "Choose to Add Onions");
tip.SetToolTip(radioButton2, "Choose to Add Pickles");
}

Why can I not call a form object in two events?

I'm making like a add contact form with two buttons, ADD CONTACT and EDIT CONTACT. When a user clicks add contact, it pops up another form where the user can add contact information.
I want to give them the option to edit that info by clicking the EDIT CONTACT button which should pop up the SAME form.
However its not letting me call the object of the form twice, saying that I cannot press the edit button after the add button.
How do I call a form object twice?
//instatiating an object of the form
FormContact contactForm = new FormContact();
public FormManager()
{
InitializeComponent();
}
private void btnAdd_Click(object sender, EventArgs e)
{
//displaying it when the user clicks add button
contactForm.Show();
}
private void btnEdit_Click(object sender, EventArgs e)
{
//trying to display it again but gives this exception
///System.ObjectDisposedException: 'Cannot access a disposed
///object.
///Object name: 'FormContact'.'
contactForm.Show();
}
Error:
///System.ObjectDisposedException: 'Cannot access a disposed
///object.
///Object name: 'FormContact'.'
The problem is you're closing the form after you've shown it.
You click the Show button
Your only instance of the form is shown
You close it with the X in the top corner
The runtime destroys the form (disposes it) after it is closed
You try to show it again but this this it's gone, trashed, doesn't exist any more, waiting to be garbage collected
Either make a new form each time you open it (to reduce code clutter, assign this same event handler to both button clicks, or copy paste it out twice if you want them to be coded differently eventually):
private void btnAddOrEdit_Click(object sender, EventArgs e)
{
new FormContact().Show();
}
Or intercept the FormClosing event of the FormContact form and cancel the closing, and perform a Hide() instead so that instead of being destroyed your form is made invisible. It will then still exist and can be Show()n the next time. To handle the event, open the FormContact designer, click anywhere in the form background, click lightning bolt in properties grid, double click the FormClosing entry:
private void FormClosing(object sender, FormClosingEventArgs e){
e.Cancel = true;
this.Hide();
}
Which method you choose depends how you want your program to behave:
If you make a new form each time, and you Show instead of ShowDialog your user could click Add twice and see two forms. Then could click Add 10 times and see 10 forms. Using ShowDialog means that the main window won't accept any more clicks until the FormContact is closed. You might or might not want this either
If you Hide (not close; hiding is different from closing) and Show the same form rather than making a new one then the user can click Add 10 times but they still only see one form
FormContact contactForm = new FormContact(); is a Member variable, it's scope is Private and is visible to the entire class.
After you first Show the form:
contactForm.Show();
The form is already showing. Therefore if you call Show again, it won't do anything as the instance of the form/class is already showing.
If you want to show two instances of the form, you will need to instantiate two instances eg:
private void btnAdd_Click(object sender, EventArgs e)
{
FormContact contactForm = new FormContact();
contactForm.Show();
}
private void btnEdit_Click(object sender, EventArgs e)
{
FormContact contactForm = new FormContact();
contactForm.Show();
}
Or make two instances of it:
FormContact contactForm1 = new FormContact();
FormContact contactForm2 = new FormContact();
private void btnAdd_Click(object sender, EventArgs e)
{
contactForm1.Show();
}
private void btnEdit_Click(object sender, EventArgs e)
{
contactForm2.Show();
}
Or add a argument in the parameter of the Constructor to indicate Add or Edit, eg:
public class FormContact
{
public FormContact(int id)
{
if (id > 0)
{
//Load contact for Editing
}
else
{
//Clear all fields for Adding
foreach(var ctrl in this.Controls)
{
if (ctrl Is TextBoxBase) ctrl.Text = string.Empty
//TODO other controls types... if (ctrl Is ....
}
}
}
}
Then you can call it passing a contactID to edit or 0 to add:
FormContact contactForm = new FormContact(contactID);
contactForm.Show();
I've got another answer, in both methods simply show your form modally:
contactForm.ShowModal();

Windows Forms - get Text value from object of type button

I have a Windows form named Form1 and panel within this form named panel1. I use the panel only to place buttons there so that I can group them and work with them separately from the other buttons in my Form1. For the purpose of my program I need to handle every button click made from the buttons inside panel1. For this purpose I use the same code snippet:
public Form1()
{
InitializeComponent();
// Set a click event handler for the button in the panel
foreach (var button in panel1.Controls.OfType<Button>())
{
button.Click += HandleClick;
}
}
What I need to do is to have a way to identify which button exactly has been clicked. For this purpose I played a little bit with my handler method:
private void HandleClick(object o, EventArgs e)
{
MessageBox.Show("HI" + o.ToString());
}
which gave me some hope because I get this:
It's the second part - Text: button4 which is actually enough information to continue with my work. But I can't find a way to get this piece of information without some complicated string manipulations. So is there a way to get this or other unique information about the button been clicked given the way I have written my code?
private void HandleClick(object sender, EventArgs e)
{
var btn = sender as Button;
if (btn != null)
{
MessageBox.Show(btn.Text);
}
}
One option is to cast the object to a Button, but rather than doing the casting you can change how the event handler is assigned so that you don't need to cast in the first place:
foreach (var button in panel1.Controls.OfType<Button>())
{
button.Click += (_,args)=> HandleClick(button, args);
}
Then just change the signature of HandleClick to:
private void HandleClick(Button button, EventArgs e);
You need to cast sender to the Button class so you can access its properties:
Button b = (Button)sender;
MessageBox.Show(b.Text);

Categories

Resources