Implementing the Right GUI Behavior for Form_Find - c#

I have a simple application that consists of 2 Forms:
Form_Main, and Form_Find.
Form_Main is a big form that has a Grid on it,
Form_Find is a small form that has a TextBox and 2 buttons("Previous", "Next") on it.
Form_Find is only shown after the user presses Ctrl-F.
So far everything works good, and I am only left with one problem,
a problem that relates to the GUI.
The problem is this:
Form_Find's .TopMost property is set to True.
It works very well when I am in the application,
but when I leave the appication open and switch to another application(e.g. a browser), Form_Main is covered by the new window(e.g. the browser) like it should,
but Form_Find is still floating and shown, covering a part of the other application's window, and disturbing.
I wanted Form_Find to somehow be a child of Form_Main,
so that If I leave/minimize Form_Main, then Form_Find will not continue to appear..
and will only re-appear once I am back to the application - to Form_Main.
To do this, I set Form_Find's .Parent property to the instance of Form_Main,
and to make it work, I also needed to write a line before it, which sets Form_Find's .TopLevel property to false.
(or else I could not set a Parent to Form_Find)
This actually worked,
and now Form_Find behaves like a child form of Form_Main:
When I switch from my application to another application, both Form_Main and Form_Find are covered by the new appplication's window.
So this problem was indeed solved,
however a new problem has raised due to it, and this new problem is what I am stuck with now.
The new problem is:
Whenever I click the "Next" button in Form_Find,
it causes the Grid control on Form_Main to lose focus.
And when the Grid on Form_Main loses focus, the Grid takes the cell that was in EditMode, out of EditMode.
And this is my problem.
This did not happen before I set Form_Main to be the Parent of Form_Find.
The reason it did not happen, was because when Form_Find is not a child of Form_Main,
then when Form_Find gets focussed, the focussed control in Form_Main never knows about it..
Form_Main may lose the focus to another form, but the control inside Form_Main will never know it and will never fire any relevant event about it(only the form will).
So you see,
to make the behavior of Form_Find be well,
I need both of these things:
1) To have Form_Find somehow a child of Form_Main, so when I switch to another window, Form_Find will not continue floating on the screen, covering other applications
2) To have Form_Find not steal focus from the focussed control on Form_Main, when I click the "Next" button on Form_Find. I did have this as long as Form_Find was not a child of Form_Main, but I lost this once I succeeded in making Form_Find be a child of Form_Main.
So my question to you:
What would be the solution to this problem?
Thank you very much

To establish the corrent parent/child behavior requested you need to pass the owner form to the child one when you open the child.
This proof of concept could be tested using LinqPad
(*I am not involved in any way with them, IMHO it is just the most useful tool that you need)
Form f1;
void Main()
{
f1 = new Form();
TextBox t1 = new TextBox();
t1.Location = new Point(0,0);
TextBox t2 = new TextBox();
t2.Location = new Point(0,30);
f1.Controls.AddRange(new Control[] {t1,t2});
f1.Deactivate += onDeactive;
f1.Show();
Form f2 = new Form();
Button b = new Button();
b.Click += bClick;
f2.Controls.Add(b);
// This line pass the F1 form
// as owner of F2 establishing the
// correct parent/child behavior
f2.Show(f1);
}
void bClick(object sender, EventArgs e)
{
Console.WriteLine("Clicked");
f1.ActiveControl.Text = DateTime.Now.ToString("hh:mm:ss");
}
void onDeactive(object sender, EventArgs e)
{
Console.WriteLine("Main Deactivated");
}

Related

Borders are not being redrawn after hiding and showing windows form

I am working on a personal project. At one point in the project you have a menu with some buttons, and one of those buttons will:
Hide current form
Create a second form and show it through ShowDialog(this)
When the second form closes, the first form will be shown again with Show()
My issue is, that after showing the first form again, a certain border is not being redrawn. The object with this border is called pnlInfoBoard.
Here is some screenshots to show the problem:
The border appears to become transparent, and this only happens after hiding and showing the form.
I found out that the second form has no influence on this, it is only the act of hiding and showing the form. I had tried providing a fix by explicitly invalidating and updating pnlInfoBoard however, this appears to have no effect.
Here is the code:
private void btnInstructions_Click(object sender, EventArgs e)
{
this.Hide();
//Instructions frmInstructions = new TowerTitans.Instructions();
//frmInstructions.ShowDialog(this);
this.Show();
pnlInfoBoard.Invalidate();
pnlInfoBoard.Update();
}
Why would this happen?
How do I fix it?

Accurately load WinForm every time it gets focus or gets created

I'm trying to simply get a form to load correctly. It is a modeless child form of a modal parent (which itself is a modeless child form of the main UI). I need to be able to interact with all forms somewhat simultaneously.
The form I want to reload has very little access by way of fixed controls. Mostly dynamic controls loaded from reading a text file (users) and placing checkboxes (1 per user in the text file in columns) on the form.
The first thing I need to do is simply to write the form accurately every time. I open the form with a button, but retain ownership to the parent. If the parent closes, all of the children should close (but not the program. The parent of this child, is a child). Ex:
private void bPermissions_Click(object sender, EventArgs e)
{
Permissions af3 = new Permissions();
af3.Owner = this;
af3.Show();
}
So I click the button Permissions and the form opens accurately. If I select it again, the form opens without the checkboxes. If I close Permissions and then try to reopen it, it does not load accurately. Only the fixed items load. I've tried to .Refresh() the parent form and the child form in various events (FormClosed, FormClosing, Load, etc.) on both the Start form and the Permissions form.
How can I refresh this form accurately every time I try to open it?
EDIT:
I'm a newb and very much enjoy doing this. But I am learning. Please be kind and point me in a direction. :-D Thank You.
EDIT2: Not modal. Modeless.
Ok. #D.. definitely led me down the path. As a Newb I promise I had to do a little head scratching.
I was making the call from onLoad
private void Permissions_Load(object sender, EventArgs e)
{
WidgetLogic.getPermText(this);
WidgetLogic.getDetailerPermText(this);
WidgetLogic.getAdminPermText(this);
}
I should have been making the call from the button prior to the page loading and passing it back from the logic to the targetForm. The form where I wanted the information to go (Permissions af3)
private void bPermissions_Click(object sender, EventArgs e)
{
Permissions af3 = new Permissions();
af3.Owner = this;
af3.Show();
WidgetLogic.getPermText(af3);
WidgetLogic.getDetailerPermText(af3);
WidgetLogic.getAdminPermText(af3);
}
Awesome Sauce!! :-D Thank You!!

MDI application issues

General description of application:
Main form as MDI Container. On application start, if there is no xml file for database configuration (it is checked in Main form) Main form i call another form as showdialog() to fill all database info to build connection string. Then i close form and open another for login, then i get back to Main form, which has Split Container (2 panels: 1-menu on top, 2-content from child forms).
I open forms with:
private void PlanButton_Click(object sender, EventArgs e)
{
plan.TopLevel = false;
KontenerMenu.Panel2.Controls.Add(plan);
plan.Dock = DockStyle.Fill;
plan.Show();
}
and close form with:
private void Plan_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = false;
this.Hide();
}
Problems i have with app:
1. When i hit Cancel button when i open ShowDialog() form for database app crashes. Cancel button is simply:
private void cancelButton_Click(object sender, EventArgs e)
{
Application.Exit();
}
2. I have problem with clicking button to open/close/open again child forms. When i hit 'X' and want o open, app crashes with exception that it cannot refer to non-existing object
3. I have several buttons when i hit one and then another one it is always below the first one and not on the top
4. For example my form is 200x200 and in right down corner i have button (so location let's say 190x190) and i hit maximize button. My button is still on 190x190 and i would like to have it on down right corner. I couldn't find any property for that. Is there any or i have to write some code for that.
I'm not sure I understood your questions. Please make them clear.
But as an answer to question #4, there's an anchor property that does what you want.
Instead of trying to exit the application from within the dialog form itself you should return a DialogResult value and test that in the main form. The cancel button on the dialog doesn't need any code, just set its DialogResult property to 'Cancel' and if you have an Ok button set its DialogResult to 'OK'.
DialogForm f = new DialogForm();
DialogResult r = f.ShowDialog();
if (r == DialogResult.Cancel)
{
Close();
}
I can immediately see a number of problems with you code, including:
If you're going to add controls dynamically using Controls.Add, you should make sure the controls you're adding are dynamically created using new(). I get a sense that you don't have a clear understanding of object lifetimes and the WindowForms control life cycle.
The Application.Exit method should be used only in unusual cases. It's purpose is to achieve exactly the result you're observing - to immediately "crash" the application. The easiest way to have a button close a modal dialog is the set the DialogResult property of the button.
Winforms has a very elegant system for placement of control on a variable sized window. In order to use this system, you should familiarize yourself with the Anchor and Dock properties that are available on all controls.
It looks like what you're doing is attempting to learn WinForms by trial and error. You can do this, but it will take much longer and be much more painful that getting a hold of a good tutorial, book, or perhaps even attending a class if you can manage it. That will allow you to take these issues one at a time and have a much more enjoyable learning experience.

How to minimize a winforms app when there is at least one modal window opened

I have two form classes (Form1 and Form2) in a Winforms App.
Form1 is like this:
Form2 is like this (ShowInTaskbar = false):
And this code on Form1:
Form2 someForm = new Form2();
private void btOpenAnotherWindow_Click(object sender, EventArgs e)
{
if (someForm.ShowDialog(this) == DialogResult.OK)
MessageBox.Show("OK!!!");
else
MessageBox.Show("Not OK.");
}
That is, a window with a button which opens modally another windows when clicked, and waits for the user to close the second window (by clicking the "OK" or "Cancel" button). And depending how it was closed, do alternating actions (represented here by the MessageBox.Show() calls).
I need:
The user can use only one window at a time. (Modal forms, That's why I used ShowDialog() instead of Show())
When the form closes, do something depending on how the form was closed (the "if (someForm.ShowDialog(this)...")
To be able (as a user) to minimize the WHOLE APP.
To be able to "unminimize" the app to the former state correctly.
The program to respond to WIN+M (minimize all) keys combination.
the above example fails in two ways:
(need 5) Doesn't respond to WIN+M
(need 3) The app seems to minimize when the Minimize title bar button is clicked, but it is an illusion because the main form (Form1) does not minimize and it is in fact just hidden behind the other opened windows. Only running the example with an empty desktop shows what really happens. Pics follow:
Before Minimize button is clicked:
After:
Note:
The Main form is not minimized
The Form2 is in the left botton corner of the screen.
Form2 is a full blown window (not a dialog window per se) and I need the user to interact with it only until it is closed and I also need the user to be able to miminize the whole app in case he needs it.
It is a shame I can't post here the real forms, It would be clearer than these mock-ups.
I need a solution that works with many levels of modal windows (not only two as this example shows). Any suggestions?
I may need a little more information about what you're trying to do here. I have a simple form (Form1) with a button on it, which calls this code:
private void button1_Click(object sender, EventArgs e)
{
Form1 form2 = new Form1();
form2.ShowDialog();
}
When I click the button, I get a second instance of the same form, but it's modal. I still have the option to minimize this second modal form (I obviously can't interact with the first form), and when I do minimize the second form it does minimize the entire application (both forms). Now obviously you're asking the question, so I don't think I'm understanding you. =) What about this scenario do you wish to change?
C
There is probably some way to hack this functionality using API calls, but I would probably suggest doing some type of overlay with a control inside your main form rather than an actual window. This would allow you to make it "modal" and still have the ability to minimize/resize the main window.

Closing dialog form closes parent form

I have been dealing with strange problem. I am using KryptonForm in a project. I have a form (say form1) and I need to open another form on a button click from this form. Here is the code:
void btn_click(object sender, EventArgs e)
{
Visible = false;
ShowInTaskbar = false;
var f = new Form2();
f.ShowDialog();
Visible = true;
ShowInTaskbar = true;
}
The problem is that when the Form2 closes it closes the Form1 also. I have tried setting DialogResult = DialogResult.None from Form2 but of no avail. Please help me.
I am always using this technique and this thing has never happened.
Yes, this code is troublesome. It goes wrong when the user closes the dialog. Windows must then find another window to give the focus to. There isn't any left in your app, your main window is invisible. It then picks a window of another app. Odds are good, for example, that this will be a window inside Visual Studio. A big one. Your main form now disappears behind it.
You need to make sure that your main window is visible again before the dialog closes. You can do so by subscribing to the dialog's FormClosing event handler. For example:
private void button1_Click(object sender, EventArgs e) {
using (var dlg = new Form2()) {
dlg.StartPosition = FormStartPosition.Manual;
dlg.Location = this.Location;
dlg.FormClosing += (s, ea) => this.Show(); // <=== Here
this.Hide();
if (dlg.ShowDialog() == DialogResult.OK) {
// etc...
}
}
}
Bugged me for days!! Found this: https://bytes.com/topic/net/answers/769433-c-showdialog-inside-showdialog-closing-both-return
The result was being passed down and I dont know why. But if after the .ShowDialog() I just put this.DialogResult = DialogResult.None, it will fix it. This shouldnt happen in the first place, but this fixes it, so I am not too bothered.
You can also try changing the dialogResult on the button itself to "None" or deleting the this.Btn1.DialogResult... from the designer which worked for some people.
https://social.msdn.microsoft.com/Forums/vstudio/en-US/543093ad-1860-4428-bae1-b0d4f112e04b/showdialog-closes-parent?forum=csharpgeneral
I know this is an old post, but I ran into this, and in my case the accepted answer (at the time I am writing this) is not helpful at all. The answer by #blind Skwirl led me to the culprit.
After 20 years of .Net programming (since it was introduced), I never noticed that BUTTONS have a "dialogresult" property. I always just set the forms "cancelbutton" and "acceptbutton" properties. What I found in my case was that (because I was doing a lot of copy-pasting of buttons), I had a bunch of buttons (not forms) that themselves had their "dialogresult" property set to "cancel", which meant that I would click a button on a dialog that would open another dialog, the "ok" button on the dialog had its result set to "cancel", and the button on the parent form ALSO had its result set to "cancel", so the dialog would close (with a result of cancel) and then the PARENT form would close with a result of cancel, confusing the heck out of me... so...
Just make sure all of your buttons have their dialogresult property set to NONE (or whatever the actual proper setting is that you want).
Bottom line, if a BUTTON (not the form) has its dialogresult property set to anything other than NONE, the form will close with that result when it is clicked (after any click event code has completed).
I hope that helps someone out there.

Categories