Issue with referencing Winform form - c#

I have bean having a issue referencing a winform form I initialize in main, the code for the referencing is as follows,
Form1 f1 = new Form1();
Application.Run(f1);
f1.changeText("Hello World");
the form itself is defined in another file. f1.changetext is a simple function which takes a string input and sets a text block element to the string, I call the function in the form class as the result of clicking a button and that works fine but when I call it in main I get no result. As a side note I have a console.writeline function in main as well that doesn't do anything but I don't know if that's related. For context I'm using Visual studio and if it wasn't obvious I don't have too much experience with coding with classes and frameworks like this. Thanks for any assistance!

I'm not familiar with Application.Run(f1); also shouldnt you change the text prior to "Running it?"
It Being:
Form1 f1 = new Form1();
f1.changeText("Hello World");
Application.Run(f1);
A way I'm sure will work (the one I use) with showing / initializing another form would be
Form1 f1 = new Form1();
f1.changeText("Hello World");
f1.ShowDialog();
Have you tried Debug to check if the code works / was read when running?
Welcome to StackOverFlow!

Related

c# - How to set all the application as the owner of Form.showDialog()

I have a Windows Desktop App with an auto-update method implemented. I want to show a custom Form (because I need to change the button texts) asking the user if he or she wants to download the new version or not when a new update is detected and I want to "block" all input actions in the Desktop App until the user has made his selection.
After reading Form.ShowDialog() documentation and several topics here saying "ShowDialog() is not making my windows modal" and several answers replying "You need to properly set the owner" I still don't understand how to set this owner. Of course if I make two forms and the first one shows the second, I can "block" the first one doing:
secondForm.ShowDialog(firstForm);
But I don't know how to make that the firstForm blocks all the application to prevent the user using a deprecated version of it.
I tried several approaches like getting the current id process (or trying to get it) and convert it to IWin32Window. But nothing seemed to work.
If you need it, I add here the code I'm using:
FormAsk formAsk = new FormAsk (param1, param2);
formAsk.StartPosition = FormStartPosition.CenterParent;
formAsk.TopLevel = true;
formAsk.TopMost = true;
formAsk.DialogResult = formAsk .ShowDialog();
if(formAsk.DialogResult.Equals(DialogResult.OK))
{
// do stuff
}
else
{
// do other stuff
}
I've also seen lots of solution implementing:
myForm.ShowDialog(this);
But VS start's crying because the types are not compatible. I'm using a MVVM pattern so I can't just set a Form as an owner because I don't have a main form. Just views in .xaml and views controllers in c#.
Edit: I would like to add few comments I learned after facing this issue that may help to understand better my situation.
The main method of the program executes the following:
[STAThread]
static void Main()
{
//stuff
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
try
{
//stuff
STAApplicationContext context = new STAApplicationContext();
Application.Run(context);
}
catch (Exception exc)
{
MessageBox.Show(exc.Message, Localization.Strings.error_popup_title);
Application.Exit();
}
}
}
And this context is the one that generates the service layer and views manager of the application. If I display the Forms in the service layer, showDialog() method can not "block" the input in the views but if I display them from the views (generated and handled by the view manager) i can. There's a communication between views and service, because actions triggered in the views have as consequence a service method call, but in this case the communication I want is the opposite: the service calling the methods in the view controllers to display the Forms by showDialog().
You need to pass an instance of the IWin32Window interface to the ShowDialog method.
IntPtr myWindowHandle = IntPtr(parent.Handle);
IWin32Window w = Control.FromHandle(myWindowHandle);
Do your Stuff in your first Form and whatever button you press to create your second Form just go like this. (Pseudo Code)
button1_click()
{
Form2 = new Form()
Form2.Owner = this;
}
and now from your Form2 you can talk to your Owner with this.Owner.Visible = false for example.
Thats how you make the Owner if thats what you asked for.
Thanks those who tried to help with your replies. However, although your answers probably will work in other circumstances, mine where a bit different.
Finally I achieved to solve it, I needed to do the handle with Forms in a higher level of abstraction. The information managed was retrieved from an asynchronous task so I couldn't use there a showDialog method and block the MainWindow of the application. Instead I did several threads, wait them and eventually show dialogs when I needed. It's not the best approach, but given the context is the only thing I could do.

Invoke throwing InvalidOperationException

I'm having a bit of an issue that I'm stumped on and I was hoping someone could shed some light on it. I have a Form called form2 and I'm running some code to add some items to the Listview(s) of that form using a MethodInvoker so that the UI thread stays responsive while I do so.
Everything runs fine with it the first time around but then when I close that form (the one with the Listview on it) and run my code again I get a InvalidOperationException: Invoke or BeginInvoke cannot be called on a control until the window handle has been created.
So I looked into this and Googled it a bit more as well as looked on StackOverflow and I saw the issue was being caused by the form not having a handle created for it since it's being disposed when it's closed the first time.
So my solution was to have it force the form to set a handle for itself via CreateControl(). Even after using this, my form still isn't setting the handle when I inspect it in the break from the exception. It has 00x0000000 or something like that, and I'm still getting my InvalidOperationException. I have also tried to checked .isDisposed() and tried to use CreateControl() after that with no luck. Have any of you guys heard of this before? The other threads on SO have yield no solutions for me.
My Code:
if (!form2.IsHandleCreated)
{
form2.CreateControl();
}
form2.Invoke((MethodInvoker) delegate
{
//Do Stuff Here.
}
So since nobody responded to this I'll answer my own question in case anybody comes across this and it helps them. I actually ended up putting this outside the scope of my new thread that was created and creating the form in a button click event. I then checked to see if my form was Disposed or still open and created new instances of the Form based on that.
This is my code:
var checkDMS = CheckIfNull(dealtxt.Text);
if (checkDMS)
{
//If DMS Deal is valid -> If Form is Closed ->
if (form2.IsDisposed)
{
// If Form not open -> Create new instance
form2 = new Form2();
form2.Show();
form2.SendToBack();
}
else
{
// If Form still open -> Close and make new instance.
form2.Close();
form2 = new Form2();
form2.Show();
form2.SendToBack();
}
runDMSQueryFromNewThread(materialCheckBox1.Checked);
}
else
{
MessageBox.Show("Cannot Pull Deal From DMS.");
}

How to close form and open another

Currently learning to code in C#. I have used the code
Form1.Hide();
Music_Menu.Show();
The names for the forms are correct and believe this should work but I get this error when I hover over the text:
an object reference is required to access non static field member or
property c#
I am betting that Music_Menu is the name of your form's class.
You need to create an INSTANCE of the form. VB did this "behind the scenes," but C# demands you get it right.
Somewhere in Program.Main(), I'll bet you have a line:
Application.Run(new Form1());
You need to keep that reference. A private static field in the Program class should work.
private static Form1 _myForm1;
private static Music_Menu _myMusic_Menu;
Then in the Main() method, change that to:
_myForm1 = new Form1();
Application.Run(_myForm1);
Then your code (where you switch) should be (in Program.cs):
_myForm1.Hide();
_myMusic_Menu = new Music_Menu();
_myMusic_Menu.Show();
Alternatively, if you want to run the code in Form1 (and assuming you want to come back to your instance of Form1:
this.Hide();
var myMusic_Menu = new Music_Menu();
myMusic.ShowDialog();
this.Show();
You'll probably have some scope issues to straighten out depending on your context, but this should get you going in the right direction.

Which way of using Application.Run() is a better practice in code below?

I want to run the login form named frmLogin on my C# application run. I have come up with two different ways to do this, I want to know if any of the two is a more preferred practice? and why? or if they are totally equal?
Also, if there is a better practice than this, what is that?
First way:
Application.Run(new frmLogin());
Second way:
frmLogin _login = new frmLogin();
Application.Run(_login);
There is no functional difference between the two.
The only real difference is the second form gives you the ability to access frmLogin after the Run method completes. So unless you actually do something to _login there is no difference here
Makes no difference. The local variable that stores the form reference exists either way, in the second snippet it just doesn't have a name.
You are however not doing this right. You can't actually tell if the login was successful. And nothing good happens when the user logs in and closes the window, your app stops running. And if you try to work around it by hiding the login window then you'll have a hard time stopping the application.
You should do it like this instead:
using (var dlg = new frmLogin()) {
if (dlg.ShowDialog() != DialogResult.OK) return;
}
Application.Run(new frmMain());

Why c# winform is not shown when called from vbscript

i've wrote a API in C# which will be used in vb6 & vbscript and assume my API details is as below:
1. there is a form in the API but it is not exposed to COM
2. there is a method called ShowForm() with code "form1.Show()". This method ShowForm() is exposed to COM so that i can call this method from vb6/vbscript.
So, my problem is:
When i call ShowForm() method in vb6 under a button click event, the form created in C# API shows up but if i instantiate the same class and call the same method in vbscript, the form dont show up.
However, if i change the code in ShowForm(),
- from "form1.Show()" to "form1.ShowDialog()", it will show in both vb6/vbscript. But, it is showed as a modal form where what i want is modeless
OR
- from "form1.Show()" to "Application.Run(form1)". It will shows up in vbscript but not in vb6 (it actually shows up in vb6, but it crash after i close the form in C#)
What can i do to make it works fine in vb6 and vbscript? Your advice is very much appreciated
PS: its not script syntax problem or COM problem. it should be something to do with form.show()/ShowDialog()/Application.Run() or message loop thingy which is something i dont really understand
My code would be more or less something like this.
//C# code
public void ShowForm()
{
m_frm.tempWebBrowser.Navigate("http://stackoverflow.com", "_self", Encoding.Default.GetBytes(""), "Content-Type: application/x-www-form-urlencoded");
m_frm.FormBorderStyle = FormBorderStyle.Sizable;
m_frm.ShowInTaskbar = true;
m_frm.WindowState = FormWindowState.Maximized;
m_frm.tempWebBrowser.Visible = true;
m_frm.Show();
}
//VB6 code, vbscript also using exactly the same code in the event
Private Sub Command1_Click()
Dim tempClass
Set tempClass = CreateObject("myClass.API")
tempClass.ShowForm
End Sub
The form is not shown exactly because of what you suggested...there is no message pump running on the thread. If you are trying to fire-and-forget the C# window from VBScript, I suggest you launch it in a seperate process. It would have the same effect as you've described. If you instead were trying to launch it and wait for the user to interact with it (say you are prompting them for info) then showing to form modally is appropriate.

Categories

Resources