0

I am developing an application in WPF. I need to load an instance of the Window class (which I call Win1 here) with which a form is filled. Then, when the Submit button is clicked, Win1 closes and only then can a new Win2 window be loaded (another class, also inherited from Window). The problem is that both of them open and I can not synchronize the data obtained from the first Win1 and pass them to the second Win2. I'm just messing up.

Someone can give me a generic idea indicating the tools and the pattern I need to do the above. For the specifications given to me, it is necessary that Win2 appears only after Win1 has finished its work.

Even though the application is more complex than I described it now, I would like to post some code, but I manage to confuse the ideas of who is reading me, so I tell you that at the moment I'm managing the windows inside the constructor of App.cs, while MainWindow.cs corresponds to Win2 and I created a new class to implement Win1.

public partial class App : Application
{
   // Params...

   public App()
   {
       Client = LoadNetwork();
       User = LoadUser(Client); // Shows Win1
       Games = LoadMinigames();
       mainWindow = new MainWindow(User, Games);
       Application.Current.MainWindow = mainWindow; // On XAML default is Hidden
       mainWindow.Show(); // Shows Win2
   }

   // Other methods...

}

The biggest problem for me is to pass User data to MainWindow and I do not have many ideas on how to deal with this case.


Update

public partial class MainWindow : Window
{
    public UserLoading ul;
    public UserRegistering ur;
    public User.UserProfile User;
    private List<Game.Game> Games;
    public Label Username;

    public MainWindow(User.UserProfile user, List<Game.Game> games)
    {
        User = new UserProfile();
        InitializeComponent();
        User = user;
        Games = games;
        Username.Content = User.Username;

        DrawList(Games);
    }

    //...

}

I realize I have explained myself a bit 'badly rereading my question several times. So I update it trying to be clearer by reporting here my answer to one of the comments.

The UserLoad method is not blocking, because inside it are instantiated classes that inherit Window (other windows for login and registration in other words) then the flow of execution proceeds and instantiates the MainWindow where naturally the argument "user" will result null because the forms have not been filled yet. I realize now that perhaps I had explained myself badly. The call of Win1 is not blocking and I would like it to return only when the user data is ready to be passed as an argument to Win2.

shogitai
  • 1,823
  • 1
  • 23
  • 50
  • Post your MainWindow constructor... should look like public MainWindow(UserType user, GamesType games){} – Nawed Nabi Zada Jul 03 '18 at 14:15
  • You have several issues. Start with moving code out of constructor (using [event](https://stackoverflow.com/a/10276293/1997232) or overriding `App`). Anyone who is not using MVVE in wpf have to look into it asap. Then your "synchronize" is basically calling members of one viewmodel from another. – Sinatr Jul 03 '18 at 14:15
  • I added a part of MainWindow code in the question. – shogitai Jul 03 '18 at 14:20
  • 1
    Honestly, I do not even know if I'm doing things the right way. If you feel that this approach is completely wrong, I have time to study some manual, so do not be trouble telling me that the code posted sucks! :-P – shogitai Jul 03 '18 at 14:22
  • 1
    But when that is said... why do you have trouble passing, it looks like you are doing correctly with the passing ? What is the problem ? – Nawed Nabi Zada Jul 03 '18 at 14:25
  • 3
    @kitsune as Nawed mentioned, you should read into MVVM. Syncing can be achieved by using the same model for two different views. – Pulle Jul 03 '18 at 14:31
  • @NawedNabiZada The UserLoad method is not blocking, because inside it are instantiated classes that inherit Window (other windows for login and registration in other words) then the flow of execution proceeds and instantiates the MainWindow where naturally the argument "user" will result null because the forms have not been filled yet. I realize now that perhaps I had explained myself badly. The call of Win1 is not blocking and I would like it to return only when the user data is ready to be passed as an argument to Win2. – shogitai Jul 04 '18 at 06:35
  • @Pulle I rewrote the whole program from scratch, but applying the MVVM pattern (which I did not know before). I must say that everything is much more orderly but above all I have solved the problem posed in my question. At this point I would say that you can try to write the answer if you care so I can mark it as the one that has solved. I say this, because I am sure there are many other people who could be in my situation, your suggestion on the use of MVVM was decisive and taught me a new way to plan and do things well. – shogitai Jul 09 '18 at 08:28
  • @kitsune i did and i will delete these comments – Pulle Jul 09 '18 at 15:00

2 Answers2

0

I have done this in the past. here is my solution:

Set Your Launch Window to Win1. Let It launch. Create a Static Method in App.cs to launch Win2. When Win1 is ok to shut down and you want Win2 to open call App.ShowMainWindow(this) from within Win1.

App.cs

public partial class App : Application
{

    static internal void ShowWin2(Win1 win1)
    {
        Win2 win2 = new Win2();
        // Copy Win1 stuff to Win2 here
        Application.Current.MainWindow = win2;
        win2.Show();

    }
}

Win1

public partial class Win1 : Window
{
    public Win1()
    {
        InitializeComponent();
    }

    private void CloseAndLaunchWin2()
    {
        App.ShowWin2(this);
        this.Close();

    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        CloseAndLaunchWin2();
    }
}
Kelly Barnard
  • 1,131
  • 6
  • 8
  • Forgive the question (probably from your point of view will be very idiotic, but it is not for me). How and where can I invoke the ShowWin2 function of the App: Application? Usually I did it inside the App constructor itself. – shogitai Jul 04 '18 at 07:07
  • As I showed in the Win1 code you call App.ShowWin2(this) in the code where you are satisfied that Win1 has served it's purpose and are ready to launch Win2 and close Win1. In my example I have a button click on Win1 calling CloseAndLaunchWin2(); which calls App.ShowWin2(this) then closes the win1. – Kelly Barnard Jul 05 '18 at 13:27
  • In my example .Net C# application that I created, I created two windows Win1 and Win2. Win1 I added 1 button with a click event. I added the static method ShowWin2 to the App.cs file, and added the code to Win1 listed above. – Kelly Barnard Jul 05 '18 at 13:33
0

As User Nawed mentioned, you should read into MVVM. Syncing can be achieved by using the same model for two different views.

You could do something like this.

var sharedContext = new MyViewModel();

var viewOne = new MyWindow();
var viewTwo = new MyUserControl();

viewOne.DataContext = viewTwo.DataContext =  sharedContext;
Pulle
  • 429
  • 2
  • 12