0

Im learning MVVM at the moment and made a Login Window which opens first. After Logging in, my MainWindow opens. The MainWindows Title is set via Property in MainWindowViewModel but doesn't shown (its empty) now when I open this window via LoginWindow instead of making it the StartUp Window.

This is the Code how I open MainWindow from Login.

LoginViewModel.cs

if (r)
{
    CurrentUser.Username = Username;
    Messenger.Default.Send(new NotificationMessage("CloseWindow"));
}

LoginView.xaml.cs

public Login()
    {
        InitializeComponent();

        Messenger.Default.Register<NotificationMessage>(this, (message) =>
        {
            switch (message.Notification)
            {
                case "CloseWindow":
                    Messenger.Default.Send(new NotificationMessage("NewCourse"));
                    var MainWindow = new MainWindow();
                    MainWindow.Show();
                    this.Close();
                    break;
            }
        });
    }

MainViewModel.cs

public MainViewModel()
    {
        if (IsInDesignMode)
        {
            WindowTitle = "Controlcenter (Designmode)";
            CurrentUserLoggedIn = "Logged in as: " + CurrentUser.Username;
            CurrentVersion = "Version: " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
        }
        else
        {
            WindowTitle = "Controlcenter";
            CurrentUserLoggedIn = "Logged in as: " + CurrentUser.Username;
            CurrentVersion = "Version: " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
        }
    }
    public string WindowTitle { get; private set; }
    public string CurrentUserLoggedIn { get; private set; }
    public string CurrentVersion { get; private set; }

I dont know why but I think MainViewModel() isn't called. Im using MVVMLight and PropertyChanged.Fody. So my ViewModelLocator looks like this

public ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

        SimpleIoc.Default.Register<MainViewModel>();
        SimpleIoc.Default.Register<DataErrorInfoViewModel>();
        SimpleIoc.Default.Register<LoginViewModel>();
    }

    public MainViewModel Main => ServiceLocator.Current.GetInstance<MainViewModel>();
    public LoginViewModel Login => ServiceLocator.Current.GetInstance<LoginViewModel>();
    public DataErrorInfoViewModel DataErrorInfo => ServiceLocator.Current.GetInstance<DataErrorInfoViewModel>();

Is there something wrong in ViewModelLocator?

Edit: MainWindow.xaml

<Window x:Class="Ui.Desktop.MainWindow"
    [...]
    xmlns:logic="clr-namespace:Logic.Ui;assembly=ControlcenterMVVM.Logic.Ui"
    Title="{Binding WindowTitle, Mode=OneWay}"
    DataContext="{Binding Main, Source={StaticResource Locator}}">

<Window.Resources>
    <DataTemplate x:Name="firmcustomerViewTemplate" DataType="{x:Type logic:FirmcustomerViewModel}">
        <local:Firmcustomer DataContext="{Binding}" />
    </DataTemplate>
    <DataTemplate x:Name="privatecustomerViewTemplate" DataType="{x:Type logic:PrivatecustomerViewModel}">
        <local:Privatecustomer DataContext="{Binding}" />
    </DataTemplate>
</Window.Resources>
<Grid>
    [...]
        <Label Content="{Binding CurrentUser}" FontWeight="Normal" FontSize="13" />
        <Label Content="{Binding CurrentVersion}" />
    </StackPanel>

    <ContentControl Grid.Row="0" Grid.Column="1" Grid.RowSpan="3" Content="{Binding}" />
</Grid>

And MainWindow.xaml.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new FirmcustomerViewModel();
    }

    private void firmcustomer_Click(object sender, RoutedEventArgs e)
    {
        DataContext = new FirmcustomerViewModel();
    }

    private void privatecustomer_Click(object sender, RoutedEventArgs e)
    {
        DataContext = new PrivatecustomerViewModel();
    }
}

So what does PropertyChanged.Fody for me now? In MainWindowViewModel i just add the Properties as follows:

    public string WindowTitle { get; private set; }
    public string CurrentUserLoggedIn { get; private set; }
    public string CurrentVersion { get; private set; }

No I compile the Project and use dotpeek to decompile the project and see, how it looks like now

public string WindowTitle
{
  get
  {
    return this.\u003CWindowTitle\u003Ek__BackingField;
  }
  private set
  {
    if (string.Equals(this.\u003CWindowTitle\u003Ek__BackingField, value, StringComparison.Ordinal))
      return;
    this.\u003CWindowTitle\u003Ek__BackingField = value;
    this.RaisePropertyChanged(nameof (WindowTitle));
  }
}

public string CurrentUserLoggedIn
{
  get
  {
    return this.\u003CCurrentUserLoggedIn\u003Ek__BackingField;
  }
  private set
  {
    if (string.Equals(this.\u003CCurrentUserLoggedIn\u003Ek__BackingField, value, StringComparison.Ordinal))
      return;
    this.\u003CCurrentUserLoggedIn\u003Ek__BackingField = value;
    this.RaisePropertyChanged(nameof (CurrentUserLoggedIn));
  }
}

public string CurrentVersion
{
  get
  {
    return this.\u003CCurrentVersion\u003Ek__BackingField;
  }
  private set
  {
    if (string.Equals(this.\u003CCurrentVersion\u003Ek__BackingField, value, StringComparison.Ordinal))
      return;
    this.\u003CCurrentVersion\u003Ek__BackingField = value;
    this.RaisePropertyChanged(nameof (CurrentVersion));
  }
}

So RaisePropertyChaned is there.

Luranis
  • 151
  • 1
  • 3
  • 10
  • `I dont know why but I think MainViewModel() isn't called` verify this by putting a breakpoint inside the function – Jevgeni Geurtsen Oct 10 '17 at 08:52
  • Can you provide your MainWindow xaml ? Maybe you forgot to specify the DataContext – yan yankelevich Oct 10 '17 at 09:01
  • Breakpoint reached. But why the Properties will not set ? – Luranis Oct 10 '17 at 09:04
  • @yanyankelevich I dont forgot it. Because if i set the MainWindow as Startup file, then it works fine. It only doesn't work if I open it from LoginView – Luranis Oct 10 '17 at 09:05
  • 1
    When call MainWindow.Show() from your loginViewModel, is your MainViewModel constructor called ? Tip: To debug binding errors, it's a good idea to look at what's happening in visual stuido output too – yan yankelevich Oct 10 '17 at 09:08
  • @yanyankelevich It should be called or? I created a Breakpoint for the constructor and it is reached. – Luranis Oct 10 '17 at 09:19
  • It's should be called. Can you provide us : your MainWindow.xaml, and the code of your Properties ? For the moment i can only think of two reasons to explain your problem : - Your properties do not call RaisePropertyChanged in setter - Your MainWindow.DataContext and/or ViewModelLocator are broken by creating new windows instead of navigating – yan yankelevich Oct 10 '17 at 09:24
  • @yanyankelevich I edited my question now and added MainWindow.xaml and xaml.cs. As I said, im using PropertyChanged.Fody which automatic adds RaisePropertyChanged and some stuff only if i add properties with just {get; set;} – Luranis Oct 10 '17 at 09:45
  • @yanyankelevich I also added the full source of the Properties. You can see, thet RaisePropertyChanges is called too. – Luranis Oct 10 '17 at 10:04
  • you are setting the FirmcustomerViewModel() as the DataContext at the MainViewModel constructor, is that correct? Can you check that once? – Karuppasamy Oct 10 '17 at 10:10
  • @Karuppasamy How you mean? I think I don't. I set FirmCustomerViewModel() as DataContext when MainWindow.xaml is loaded (after InitializeComponent();) – Luranis Oct 10 '17 at 10:12
  • 1
    DataContext = new FirmcustomerViewModel(); this is what breaks your code. It invalidate this xaml line DataContext="{Binding Main, Source={StaticResource Locator}}" and delete the binding between your vm and your view. Navigation can be a real pain in this *** with mvvm light, i highly recommand you to do some research about it (https://stackoverflow.com/questions/28966819/mvvm-light-5-0-how-to-use-the-navigation-service) and to avoid setting manipulating ViewModels in any way from code behind (aka xaml.cs) – yan yankelevich Oct 10 '17 at 10:21
  • @yanyankelevich Thats so complicated.. I even cant use it because of the "new Uri("../Views/Login.xaml")" because I have this in Ui.Desktop Project. Mvvm is so hard to learn.. – Luranis Oct 10 '17 at 11:16
  • If you think this is to hard for you I would suggest to try another mvvm framework with more documentation, tutorials and already coded behaviours (navigation being one of them) like Mvvmcross. MvvmLight, as it's name suggests, offer a simple mvvm framework easily customisable but recquires that you code yourself most of basic behaviours (again, navigation being one of them) – yan yankelevich Oct 10 '17 at 12:51

0 Answers0