简体   繁体   中英

WPF: Managing windows (opening, closing, etc...) in MVVM?

I've read about it in a bunch of places. Most of the people are referring to these two links:

I don't understand either of them. I am a beginner when it comes to MVVM. Some people are mentioning controllers when it comes to window manipulation in MVVM. What are those and how are they implemented? By book , MVVM is consisted of model, viewmodel and view - where do controllers come in?

If someone could provide a sample of the following use case, that would be terrific (for all those people who are just getting started with this, as I am):

  1. Prerequisite: A window is opened.
  2. User clicks a button.
  3. New window is opened and some data is passed to that window, ie some string.
  4. New window is closed (or a button is clicked) and some data is passed to the first window.
  5. Passed data has changed something on the window.

The ViewModel to ViewModel communication is usually handled by an implementation of the Event Aggregator pattern.

MVVM Light uses the Messenger class, Prism has another implementation but basically that is one way to send messages between View Models without coupling.

There are some examples, and Articles describing the usage. I would suggest taking a look at it.

Regarding the controllers stuff in WPF, I don't know.

Regarding the example:

-I Have a Windows with its WindowsViewModel. This class should have a Command bound to the Button.

-The user clicks the button. Executes the command.

-The Command opens a new Window.

Here you should create the Dialog View Model and somehow you should create the Window. Or create the Window with a ViewModel, but ViewModel shouldn't know much about the View otherwise is not testable.

We use something like this because we have some requirements, but it could be much much simplier, it happens it's the only example I have at hand:

bool? ShowDialogImpl<TViewModel>(Action<TViewModel> setup) where TViewModel : ViewModel
{
    return (bool?)DispatcherHelper.UIDispatcher.Invoke(
        (Func<bool?>)(() =>
        {
            var viewModel = viewModelFactory.Get<TViewModel>();
            viewModel.ViewService = this;
            setup(viewModel);
            var window = new Window
            {
                Owner = this,
                SizeToContent = SizeToContent.WidthAndHeight,
                WindowStartupLocation = WindowStartupLocation.CenterOwner,
                Content = ViewFactory.CreateView<TViewModel>(),
                DataContext = viewModel,
                WindowStyle = WindowStyle.ToolWindow,
                ShowInTaskbar = false
            };
            window.SetBinding(TitleProperty, new Binding("Title"));
            openDialogs.Push(window);
            window.Activated += (sender, args) => window.SizeToContent = SizeToContent.Manual;
            var result = window.ShowDialog();
            openDialogs.Pop();
            viewModelFactory.Release(viewModel);
            return result;
        }));
}

Basically: We create a window and with a view model. The view model is created from a factory using an container. The setup Action delegate is the entry point for our data.

  • Communication:

The first Windows is a Grid, and the second Dialog to edit data of the grid. Inf the Windows we have:

messenger.Register<EntityUpdated<FooClass>>(this, message => UpdateItem(message.Entity));

And in the Dialog:

messenger.Send(new EntityUpdated<FooClass>(subject));

This way, we know when something was updated in the Edit Dialog in order to refresh the grid.

Hope this help you:)

If you aren't planning on allowing the user to switch back and forth between the windows, while both are open (ie, the first opens the second, and the second must be closed to return to the first), you could simply set the viewmodel for both windows to the same viewmodel instance, and open the 2nd window as modal, and the strings you are passing back and forth, would simply be properties of the view model, with data bindings to something in the view.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM