开发者

Property in ViewModel not displayed in View

开发者 https://www.devze.com 2023-03-12 13:25 出处:网络
I have a ViewModel called MainWindowViewModel. In this I have a property that shows a modal window when an error occurs. This works fine as long as an error occurs during start-up.

I have a ViewModel called MainWindowViewModel. In this I have a property that shows a modal window when an error occurs. This works fine as long as an error occurs during start-up.

When an error occurs after start-up, in SubViewModel, I invoke the parametrized constructor in MainWindowViewModel.

MainWindowViewModel.cs

public MainWindowViewModel()
{
    if (!isServerRunning)
    {
        this.ModalWindow = new LogViewModel("Server is down.");
    }
    else
    {
        this.ModalWindow = new LogViewModel();
    }
}


public MainWindowViewModel(string logMessage)
{
    this.ModalWindow = new LogViewModel(logMessage);
}


public LogViewModel ModalWindow
{
    get
    {
        return _modalWindow;
    }
    set
    {
        _modalWindow = value;

        OnPropertyChanged("ModalWindow");
     }
}

MainWindow.xaml

....

<Grid>
    <vw:LogView Content="{Binding Path=ModalWindow}"/>
</Grid>
  • MainWindowViewModel is bound to MainWindow.xaml

  • SubViewModel is bound to SubView.xaml

  • MainWindow.xaml loads multiple views, one of them is SubView.

In App.xaml I have created an instance of the ViewModel and bound it to MainWindow.

protected override void OnStartup(StartupEventArgs e)
{                                  
    base.OnStartu开发者_StackOverflow中文版p(e);
    MainWindow mainWindow = new MainWindow();
    MainWindowViewModel viewModel = new MainWindowViewModel();
    mainWindow.DataContext = viewModel;
    mainWindow.Show();
}

What I realized was that the modal window shows up when an error occurs after start-up if I create the modal window property in SubViewModel and bind it to SubView. But this is not ok since SubView is only a DockPanel covering 1/4 of the MainWindow. I.e. 1/4 is only covered with a modal window instead of the whole MainWindow.

I am not sure why modal window does not appear in MainWindow when I call the parametrized constructor from SubViewModel. When I debug I see that the part _modalWindow = value; has correct values but in any case the modal window does not show up.

I am binding the ViewModel to the Datacontext of the MainWindow. That's is probably why I see the Modal window when error occurs on start-up. For errors after start-up: Must I (from SubViewModel where I invoke the parametrized constructor in MainWindowViewModel) do some kind of binding to the datacontext of the Mainwindow again? How is the best way of doing this without having to create a new instance of MainWindow? Because MainWindow should only be created once.

Any help is much appreciated.


It looks like you are recreateing the ViewModel every time an error occours. If so you would need to reset the binding in the view as well, which would defeat the purpose of MVVM. Rather have one instance of the ViewModel and propagate the errors to the View using OnPropertyChanged().

There are of course many ways of doing this, but I usually keep a reference to the ViewModel in my View, and then a reference to the Model in the ViewModel. This way the Model is completely decoupled from the View/ViewModel and likewise the ViewModel is decoupled from the View.


You should not create MainWindowViewModel again and again. It should be created once and set to the datacontext of the mainwindow.

The problem is with the approach that you are taking to show dialog boxes. This is making things complicated.

The best solution to show dialog boxes is to use mvvmlight toolkit's messenger. Check this for some hints on it's usage.

This is how you could use mvvmlight toolkit's messenger to show dialogboxes:

View:

Messenger.Default.Register<DialogMessage>(
         view,
         msg =>
         {
             var result = MessageBox.Show(
                 msg.Content,
                 msg.Caption,
                 msg.Button,
                 msg.Icon);
         }
);

ViewModel:

private void ShowMessageBox(string msgStr, string capStr, MessageBoxButton btn, MessageBoxImage img)
{
        var message = new DialogMessage(msgStr, null)
        {
            Button = btn,
            Caption = capStr,
            Icon = img
        };

        Messenger.Default.Send(message);
}

Just call the above method (ShowMessageBox) from any viewmodel to show a dialogbox.

0

精彩评论

暂无评论...
验证码 换一张
取 消