Here's the situation. I've been developing a serial communication application and I needed multiple instances of my main form to show up when I click on a ListView item. Everything was running fine before I added this code:
private void ListView_DeviceList_MouseDoubleClick(object sender, MouseEventArgs e)
{
ListViewHitTestInfo hit = ListView_DeviceList.HitTest(e.Location);
if (hit.Item != null)
{
Form m = new Form1();
m.Show();
}
}
After I tried to run it and double clicked in my ListView new instance of my form opened up as expected. The problem was they were glued together and I couldn't see the first one. After I closed it and tried to run it again it didn't show up. I could see the application running in the task manager and there was the icon in the windows taskbar but no UI opened up... Sorry this might be really unclear but I don't know how to describe it differently.
Related
I'm studying to become a developer; as a formative project, I'm working on a desktop app to help me organize local amateur chess tournaments with MAUI. Basically, I want to be able to open multiple windows during the same execution, so that I can run various parallel tournaments on the same machine.
On the MainPage I placed a button that creates a new window that displays the NewTournamentPage
private void NewTournamentButton_Clicked(object sender, EventArgs e)
{
Application.Current.OpenWindow(new Window()
{
Page = new NewTournamentPage()
}) ;
}
in the NewTournamentPage I placed a button to add a new player to the tournament, and I want the window to freeze until the user inserts the player name, but without blocking the execution of the other windows. DisplayPromptAsync seems to be exactly what I'm looking for, so I did this:
public async void AddNewPlayer_Clicked(object sender, EventArgs e)
{
string newPlayerName = await this.DisplayPromptAsync("Add new Player", "Name:");
//code to add player to tournament
...
}
When I execute and click the NewTournamentButton multiple times, the windows are created with no problems, and they all work independently from each other, but when I press the AddNewPlayer button, the popup pops on the MainPage window, not on the one calling the method, and it takes and saves the input in newPlayerName; then, the same thing happens on all secondary windows, in order of creation, without updating newPlayerName. What is happening here? What am I missing?
Yes, it is just the case as you said. And I have created a new issue about this problem on github.
You can follow it up here: https://github.com/dotnet/maui/issues/7650.
Thanks for your feedback and support for maui very much.
I want to create an autologin WinForms app with TestStack.White. Here is my code:
private void button1_Click(object sender, EventArgs e)
{
Process[] process = Process.GetProcessesByName("XYapp");
TestStack.White.Application app = TestStack.White.Application.Attach(process[0].Id);
TestStack.White.UIItems.WindowItems.Window window = app.GetWindow("XYwindowName", TestStack.White.Factory.InitializeOption.NoCache);
TestStack.White.UIItems.Panel panel = window.Get<TestStack.White.UIItems.Panel>(TestStack.White.UIItems.Finders.SearchCriteria.ByText("Login"));
panel.Click();
...
}
The XY app main window has 10+ panels and one of them is the "Login" panel. When I click the button1, the XY app "Login" panel will be visible, so it works.
But my WinForms app freezes and I get the control back when I close the XY program but I want to run further.
In debug mode, the following error message is displayed:
"Managed Debugging Assistant 'DisconnectedContext' : 'Transition into COM context 0x15305d0 for this RuntimeCallableWrapper failed..."
I think I understand why I get this message, but I have no idea what the solution is.
Someone could help me?
thanks
I'm sorry for the stupid question, the solution is simply just make a new thread.
https://learn.microsoft.com/en-us/windows/desktop/winauto/uiauto-threading
I'm trying to create two Windows Forms with buttons in order to linking them to each other, using this code:
private void cmdInformation_Click(object sender, EventArgs e)
{
frmInformation information = new frmInformation();
information.Show();
}
(It's the same way for the second form)
When using this code you will have multiple windows of same form if you keep clicking the buttons. What can I do to stop this?
The best solution will be linking forms together without creating a new one, but I don't know any other way than one above.
Tested Hide() but it just hides the multiple windows and program remain open even if you close last shown window.
Tried Close() but when it close the main form whole program is ended.
Use a dialog.
information.ShowDialog();
You can also read up on dialog results and get responses from your form if that is needed.
Move the creation of the opposing form outside of the click event.
frmInformation information = new frmInformation();
private void cmdInformation_Click(object sender, EventArgs e)
{
information.Show();
}
This will re-display the same form over and over maintaining any data even when the user closes it.
An option would be to create a FormFactory that keeps track of the instances, this way if the form doesn't exist you can create a new instance and show it. If the form exists you can just show the current instance.
I'm having a problem that I've been trying to solve for days now, but without luck!
On my Windows Forms Application I have a grid. One column contains an email address. When the user double clicks this column, I want to open a new E-Mail Window via Outlook automation. This window should have the focus and allow the user to type immediately.
Everything works fine, when:
I'm running my app from Visual Studio.
Or my app has the focus.
However, when I run my .exe and outlook has the focus when I double click the column, the following happens:
The new Mail window opens as expected
The cursor blinks in the new mail window (as expected)
when the user starts typing, the cursor still blinks in outlook but the typed text appears in the grid of my application, not in outlook.
I was able to reproduce the problem with a simple form that has a textbox on it.
I use the following code:
private void textBox1_MouseDoubleClick(object sender, MouseEventArgs e)
{
OpenOutlookMail(textBox1.Text);
}
private void OpenOutlookMail(string to)
{
MailItem item = OutlookApp.CreateItem(OlItemType.olMailItem) as MailItem;
item.To = to;
item.Subject = string.Empty;
item.Body = string.Empty;
item.Display();
}
protected Application OutlookApp
{
get
{
if (mOutlookApp == null)
{
mOutlookApp = new Application();
}
return mOutlookApp;
}
}
What i already tried was to
Activate my current form via this.Activate() before the call to OpenOutlookMail
Activate the MailItem Inspector Object
Activate the ActiveWindow and ActiveExplorer of Outlook via Automation
Using AutoIt as explained here Similar Problem with MS Word on the MSDN Forum
Any help would be appreciated!
I wrote about focusing a background window some time ago:
http://blog.sebastianbrand.com/2010/02/activate-form-in-background.html
private void label1_Click(object sender, EventArgs e)
{
// mainform.BringToFront(); // doesn't work
BeginInvoke(new VoidHandler(OtherFormToFront));
}
delegate void VoidHandler();
private void OtherFormToFront()
{
mainform.BringToFront(); // works
}
If you do have an handle of the bad window, give that a try.
You can try to use Dispatcher.BeginInvoke(...) with some low priority in your textBox1_MouseDoubleClick(...) method to call OpenOutlookMail(). It often helps to workaround focus management issues like this one.
I haven't been able to reproduce the problem with your code. I've used Microsoft.Office.Interop.Outlook version 14.0.0.0 and in every tests i've done the mail window get the focus.
As you state,
Everything works fine, when:
•I'm running my app from Visual Studio.
•Or my app has the focus.
Maybe trying to focus your form and/or making your application sleep before opening the mail window would work
private void textBox1_MouseDoubleClick(object sender, MouseEventArgs e)
{
this.Focus();
System.Threading.Thread.Sleep(500);
OpenOutlookMail(textBox1.Text);
}
Interops often have weird behaviors. :s
I'm maintaining a C# .net program that uses Castle Windsor as a framework. It also uses Skincrafter to decorate the forms.
In it we have functionality that detects the presence of a file on a USB device and produces another form to deal with it. The software checks for the file either when a USB Event is raised by Windows or when the user presses a button that forces a recheck.
When the user forces a recheck, if the file is found the form appears on top of the main form and is decorated by Skincrafter. If a USB event is raised then the form is produced, but doesn't appear on top (Have to click on it in the task bar to see it) and is not decorated by Skincrafter.
Both methods for detecting the file reach the same function which tells another part of the program to produce the form to deal with the file. The only difference I have found when debugging is that the force recheck method uses the Main Thread whilst the USB Event method has it's own child thread that goes through to the form being shown.
Is it the seperate thread that's causing Windows not to produce the form on top (And presumably be ignored by Skincrafter) or is there likely some other issue?
I can post code if required, but the code paths are identical other than the method calling the file check and the data is identical.
Edit - Code:
This is a simple reconstruction that I produced. New WinForms project with System.Management added to references. Just make a form (FormStartPosition set to CenterScreen) with a button and use this code:
public partial class Form1 : Form
{
private ManagementEventWatcher _eventWatcher = null;
int devices = 0;
public Form1()
{
InitializeComponent();
WqlEventQuery q = new WqlEventQuery();
q.EventClassName = "__InstanceOperationEvent";
q.WithinInterval = new TimeSpan(0, 0, 3);
q.Condition = #"TargetInstance ISA 'Win32_USBControllerDevice' ";
_eventWatcher = new ManagementEventWatcher(q);
_eventWatcher.EventArrived += new EventArrivedEventHandler(UsbEventArrived);
_eventWatcher.Start(); // Start listen for events
}
private void UsbEventArrived(object sender, EventArrivedEventArgs e)
{
if(System.Environment.GetLogicalDrives().Length - devices != 0) {
ShowThingy();
devices = System.Environment.GetLogicalDrives().Length;
}
}
private void button1_Click(object sender, EventArgs e)
{
ShowThingy();
}
private void ShowThingy()
{
Form form2 = new Form();
form2.Size = new Size(50, 50);
form2.StartPosition = FormStartPosition.CenterParent;
form2.TopMost = true;
form2.ShowDialog();
}
}
Run and insert a USB Device and the form2 Form should appear behind the main form.
This doesn't seem to recreate the problem each time. But the first time I plug a USB device always seems to create the second form behind the first. Clicking the button produces the second form on top every time.
I should note that I'm running Windows 7.
You're not setting the owner for the modal window, and the default is the active window (which may not be your main window).
What happens if you use the overload of ShowDialog that takes an owner?
form2.ShowDialog(this);
If that doesn't work, it smells strongly of a threading issue. Can you try changing your USB event handler to use Invoke on the form?