0

I'm still learning this C# MVVM WPF thing and I'm having some troubles in understanding some concepts I already tried some things similarly but sadly without results.

So I want to >>> if the Login was successful to open a new ViewModel passing one class (you can see in comment, the exact place) to the GeneralViewModel can someone help me here some code so that you can understand better.

Thanks in advance :)

LoginViewModel

    WifiAP wa;
        #region fields
        private TokenRequest tk;
        public DelegateCommand _loginCommand { get; set; }
public LoginViewModel()
            {
                wa = new WifiAP();
                _loginCommand = new DelegateCommand(
                 (s) => { login(); }, //Execute
                 (s) => { return !string.IsNullOrEmpty(_email); } //CanExecute
                 );

            }
            public DelegateCommand LoginCommand
            {
                get { return _loginCommand; }
            }
    public async void login()
            {
                var sendRequest = new TokenRequest
                {
                    email = Email,
                    mac = getMac(),
                    platform="windowsdesktop"
                };

                //Get Token
                var response = await CommunicationWebServices.PostASM("self/token", "",sendRequest);
                if(response.StatusCode == HttpStatusCode.OK)
                {
                    string responseS = await response.Content.ReadAsStringAsync();
                    var aux =  JsonConvert.DeserializeObject<TokenOK>(responseS); // I have the Token in the Aux
                    var passwordMD5 = hashingMD5(Password);
                    var stringConcat = aux.token + passwordMD5;
                    var finalMD5 = hashingMD5(stringConcat);
                    // Now you can login
                    var sendRequestLogin = new LoginRequest
                    {
                        email = Email,
                        tokenpassword = finalMD5,
                        mac = getMac(),
                        platform = "windowsdesktop"
                    };
                    var responseLogin = await CommunicationWebServices.PostASM("self/login", aux.token, sendRequestLogin);
                    if(responseLogin.StatusCode == HttpStatusCode.OK)
                    {
                        string responseL = await responseLogin.Content.ReadAsStringAsync();                    
                        var auth = JsonConvert.DeserializeObject<LoginAnswer>(responseL);
                        // Change to GeneralViewModel and send the auth variable
                    }else {//...}}

LoginView

    <UserControl.DataContext>
            <ViewModel:LoginViewModel/>
        </UserControl.DataContext>
    <Button x:Name="buttonLogin" Content="Login" 
Command="{Binding LoginCommand}" HorizontalAlignment="Left" Margin="274,305,0,0" VerticalAlignment="Top" Width="248" Style="{DynamicResource FlatButtonStyle}" Height="30" />
Antoine
  • 312
  • 1
  • 5
  • 18
  • Hi @PeterB can you explain me better? The LoginCommand is called correctly, I just want in the middle of the login function to change to the generalview and send the var auth (answer from the webservices) – Antoine Apr 29 '16 at 10:59
  • Seems like I misunderstood the question, I thought you wanted to insert a new ViewModel as the GeneralViewModel. – Peter B Apr 29 '16 at 11:01
  • No, PeterB. That I already know how to it. I just want to know how to send a class through the ViewModel, instead of just changing using binding in the view. – Antoine Apr 29 '16 at 11:06

1 Answers1

1

Starting from this previous answer, you simply need a slight change, so that you can call

windowFactory.CreateNewWindow(newViewModel);

That can be easily implemented as

public class ProductionWindowFactory: IWindowFactory
{

    #region Implementation of INewWindowFactory

    public void CreateNewWindow(AViewModel newWindowViewModel) 
    {
       NewWindow window = new NewWindow()
           {
               DataContext = newWindowViewModel;
           };
       window.Show();
    }

    #endregion
}

so in conclusion your code could be like

 GeneralViewModel generalViewModel = new GeneralViewModel(auth);
 windowFactory.CreateGeneralWindow(generalViewModel);
Community
  • 1
  • 1
  • Giulio8 thanks for your answer, I have a doubt: In the MainWindowViewModel or in the LoginViewModel? – Antoine Apr 29 '16 at 13:32
  • I think you can add the last two lines in the LoginViewModel where you wrote: // Change to GeneralViewModel and send the auth variable –  Apr 29 '16 at 13:34
  • Something is wrong. Is not working :s ... I'm working with Views not windows and using MVVM architecture; don't know if that causes some difference. – Antoine Apr 29 '16 at 13:46
  • It's the same, no problem. Edit your question with the details of what is not working now... –  Apr 29 '16 at 13:50
  • I can't use the ViewModel newWindowView model. It says that is a namespace and it's used like a type. – Antoine Apr 29 '16 at 13:52
  • Sorry, I've fixed it's ViewModelBase or what is the base class you use for ViewModels or just the NewWindowViewModel itself –  Apr 29 '16 at 13:55
  • Now that part is working :D but I still have problems in the NewWindow. I should name it what? GeneralView? GeneralViewModel? – Antoine Apr 29 '16 at 14:06
  • Correct, NewWindow is your GeneralView (that is not in the question) Its DataContext will be the GeneralViewModel... –  Apr 29 '16 at 14:10
  • But for putting GeneralView in the GeneralViewModel I loose the MVVM architecture right? – Antoine Apr 29 '16 at 14:11
  • In fact you **don't** put it in the GeneralViewModel but in the implementation of IWindowFactory ! (DI-IoC pattern!) So you're not losing the MVVM pattern at all –  Apr 29 '16 at 14:12
  • DataContext = newWindowViewModel (why did you change it?) and I don't know if you already implemented the GeneralView control with another name (you should share all your relevant code...) –  Apr 29 '16 at 14:21
  • I changed to this: http://i.imgur.com/ZFLF6lM.png but I need to pass the class AuthenticatedUser. Can I pass it here? – Antoine Apr 29 '16 at 14:26
  • The error you are showing is because the constructor of GeneralViewModel requires the authenticated user. No problem, you can delete the first CreateNewWindow() and keep only the second one as in my answer (I've edited it again, BTW these are minor details) –  Apr 29 '16 at 14:35
  • http://i.imgur.com/qhRqzzN.png and in DataContext it says that the ViewModel does not contain a definition for that.. Strange – Antoine Apr 29 '16 at 14:45
  • it's not strange: it's DataContext = newWindowViewModel –  Apr 29 '16 at 14:48
  • DataContext = newWindowViewModel; //look at my answer and GeneralViewModel window is wrong. You have to use the Window or the View... –  Apr 29 '16 at 14:48
  • :O that is done. But the others is not http://i.imgur.com/mB8hVzT.png after working can you explain me why? It feels kinda magical :O – Antoine Apr 29 '16 at 14:51
  • it's simple: you have to create your UserControl (in my example it's a Window) and assign its DataContext to the ViewModel. From the last image mB8hVzT.png you have to use your View (it's a window in my case) Where is it? The type of window can't be GeneralViewModel –  Apr 29 '16 at 14:57
  • "View window = new GeneralView()" has to be changed according to the code you developed. First of all, do you want to change the view or only the viewmodel? I assume you want to change also the view: where is the new view you want to move to? You wrote "I want to change to the generalview ": So where is this generalview? You need to do "GeneralView generalView = new GeneralView()" –  Apr 29 '16 at 15:22
  • Trying to clarify. The code is implemented in the LoginViewModel. I want to change to the GeneralViewModel (that "opens" the GeneralView)...I want to send the AuthenticatedUser object from the LoginViewModel to the GeneralViewModel... – Antoine Apr 29 '16 at 15:27
  • "GeneralViewModel (that "opens" the GeneralView)" is wrong. GeneralViewModel is a ViewModel and can't open a View (GeneralView is a View, correct?). You have to instantiate GeneralView in this ViewFactory.. –  Apr 29 '16 at 15:29
  • ".I want to send the AuthenticatedUser object from the LoginViewModel to the GeneralViewModel" that is easy: you just create GeneralViewModel from the LoginViewModel passing the AuthenticatedUser. But then you have to do the binding for this GeneralViewModel: so where is the View that binds GeneralViewModel? –  Apr 29 '16 at 15:35
  • Q1: I have the correct DataTemplates in XAML. Its just call the ViewModel and the view changes automatically. Q2: If I do this [this.AddViewModel(new GeneralViewModel() { DisplayName = "General", InternalName = "GeneralViewModel" });] works? – Antoine Apr 29 '16 at 15:46
  • Q1 => does "call the ViewModel" mean "change the DataContext of an element of your XAML"? If yes you have to bind that DataContext to a ViewModel Property and set it accordingly –  Apr 29 '16 at 15:49
  • Yes. The DataContext changes. But that I've already achieved. I just down know how to that from the ViewModel in itself and to pass values, if instead of //change view model here I put LoginViewModel.AddViewModel(new GeneralViewModel()} works? – Antoine Apr 29 '16 at 15:53
  • I think you misunderstood what I've said. Anyway what is the content of loginViewModel.AddViewModel? is it a function of your LoginViewModel? Well, and what is it doing? –  Apr 29 '16 at 15:57
  • It's a function that I've implemented in the AViewModel http://i.imgur.com/x35fFY6.png – Antoine Apr 29 '16 at 16:09
  • Well, it seems ok. I suspect that maybe you should have used the Mediator Pattern in the first place, but of course I don't know all the details of your specific implementation... So ok :) I have to go now –  Apr 29 '16 at 16:18
  • Just out of curiosity, I'll tell you my approach for a similar situation in one of my apps. I've defined an attached property in my custom grid in the xaml, so I can set an enum in the viewmodel from let's say Main to Check and (via binding + dependency property's value-changed handler) I get a metro-style transition in the view content :-) cool! –  Apr 29 '16 at 21:26
  • You are in an advanced level, I'm having real troubles here :( – Antoine Apr 30 '16 at 15:59
  • still in trouble? why? –  Apr 30 '16 at 17:32
  • Please move this to a chat (in case you want to continue) –  Apr 30 '16 at 17:40
  • yes, if you can talk to me I would thank you very much. – Antoine May 01 '16 at 18:27