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.
Related
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.
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 troubles understanding how can I execute code when doing fast app switching (i.e. pressing the Windows/Start button to show Start screen on the Phone emulator, and then pressing the Back button to go back into the app).
To simplify the issue, I started a new Windows Universal App that uses the "Visual C# Hub App (Universal Apps)" template as base code (since it includes the SuspensionManager and the NavigationHelper). Since I'm not interested in the Hub itself, I removed all the Grid content from the HubPage.xaml and simply added a TextBox called TimeTextBox:
...
<Grid x:Name="LayoutRoot">
<TextBox Name="TimeTextBox"/>
</Grid>
</Page>
Then, in the HubPage.xaml.cs, I added the following simple line to the method NavigationHelper_LoadState:
private async void NavigationHelper_LoadState(object sender, LoadStateEventArgs e)
{
var sampleDataGroups = await SampleDataSource.GetGroupsAsync();
this.DefaultViewModel["Groups"] = sampleDataGroups;
TimeTextBox.Text = DateTime.Now.TimeOfDay.ToString();
}
If I execute the app on the Phone emulator after applying those simple changes, the app will show the time of the day when loading the page, for example: 16:08:53.4390827.
What I want is that time to be updated every time I navigate to that page. But I if use the Lifecycle Events from Visual Studio to simulate a Suspend, when I send the Resume event the time is still the same: 16:08:53.4390827, and a breakpoint in that line will confirm that the NavigationHelper_LoadState method doesn't get executed when resuming.
The explanation for this is that the App.xaml.cs, as it is in the template, doesn't provide any listener for the Resume event, so nothing gets executed. Adding the next few lines fixes that:
public App()
{
this.InitializeComponent();
this.Suspending += this.OnSuspending;
this.Resuming += App_Resuming;
}
async void App_Resuming(object sender, object e)
{
await SuspensionManager.RestoreAsync();
}
So if I run again the app on the Phone emulator, now I get the actual time after resuming. Great! The problem is that these Suspend/Resume events don't get triggered when I simply tap on the Windows button of the Phone and then tap on the back button.
Actually, I haven't been able to identify one single method that gets executed when performing that kind of fast app switch. And that's the scenario I'm actually interested for my Universal App.
Is there a way of catching when the navigation brings us back into the app from the Start screen through the Back button? Am I missing any code to handle this scenario?
Thanks!
There's nothing wrong here. It's the default behavior. When you debug a Windows Phone 8.1 app from Visual Studio, the only way to trigger Suspend/Resume event is using the Lifecycle Events in VS. But when you run the app without VS, those methods will trigger as expected. :)
App I am trying to create in WPF/C# has quite a few buttons in a layout with a "TV screen" type panel above (its actually an FMS emulator for commercial aircraft). Many of the buttons change the layout, which are numerous TEXTBOXs on the tv screen. My question is: is there a provision to encapsulate the layouts in different classes/files and load them into the "tv screen" at the selection of the various buttons? In other words, user hits the Flight Plan button and the layout of the 355x355 box (screen) above loads the XAML "flight_plan" layout/file/class. Each layout has different TEXTBOX sizes & locations and there are in excess of 30 different "pages", which would make encapsulating them desirable.
I am very new to WPF and c#, but have written win apps in c++ all the way back to Turbo C & OWL. I also may be trying to do something that isn't possible due to working lately in Android/Java and am confusing capabilities.
Thanks in advance.
Edit
Thanks to #adityaswami89 and everyone else who got me on the right track, I have found the solution. I added the pages via a new "WPF Page" in VS2012. Then changed the "screen" to a navigation frame and it was truly simple from there. Below is the simple project I created to test it.
public partial class MainWindow : Window
{
NavRad navrad = new NavRad();
FPlan fplan = new FPlan();
public MainWindow() {..}
private void Frame_Navigated_1(object sender, NavigationEventArgs e) {..}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
Screen_Frame.Navigate(fplan);
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
Screen_Frame.Navigate(navrad);
}
You can also use the concept of Frames for the intended functionality , if that can be an option you are looking.
You can refer the below link for the same.
http://msdn.microsoft.com/en-us/library/ms750478.aspx#Frame_in_Standalone_Applications
You can abstract the different UI Layout Sets within different User Controls and load them according your UI logic. One way to do this is using an MVVM framework, for example, Caliburn Micro makes this a pretty simple task as doing:
ActivateItem(UILayoutViewModel);
And this call can be called from any method.
See more of Caliburn Screens and Composition at official source.
I want to have a lot of forms in my Gtk# application. I want to quit application when user close all form. I try to use next code:
protected void OnDeleteEvent (object sender, DeleteEventArgs a)
{
/*Application.Quit ();
a.RetVal = true;*/
if(System.Windows.Forms.Application.OpenForms.Count==0)
{
Gtk.Application.Quit ();
a.RetVal = true;
}
}
But System.Windows.Forms.Application.OpenForms.Count allways return "0" regardless of the number of open forms (OS Ubuntu 12.04). How can I solve this problem and get actual quantity of open forms?
Thanks in advance
also tried to find an answer to that issue.
My current implementation is based on some concept I have seen in MS Visual Studio documentation:
in the project's main class maintain a static list of open windows.
do not use the delete event but the destroy event of the GTK# window (with the OnDelete event handler something did not work, if I remember correctly the windows delete cannot be directly called by a member function).
In the OnDestoy event handler: when the window gets destroyed then remove it from the static list. Then check the list for being empty, then quit the application.
Not sure if this is really ideal for GTK# windows but in my application this concept works.
regards
Harald