티스토리 뷰

Edit: See my blog post for a more detailed explanation.

When I need to achieve that, I use a IRequestCloseViewModel interface that I created.

This interface contains only one event: RequestClose. This event is raised by the ViewModel (which inherits from a ViewModelBase class AND implement IRequestCloseViewModel) when it wants to close its associated view.

In my app, all Window inherit from an abstract class ApplicationWindow. This abstract class is notified each time the DataContext changed and in the handler checks if the DataContext support the IRequestCloseViewModel. If this is the case, an event handler is set up to close the Window when the event is fired.

Alternatively, like Kent said, you can use screen controller that handle this mecanism in an external class.

-------------------

Not sure what MVVM framework you are using, but most contain some sort of messaging / notification solution that is easy have things register for messages which are sent. There is no reason that I can imagine that your view could not register for a message such as "CloseWindowsBoundTo" and the viewModel as the sender. Then in your view, you can just register for that message, and compare your current datacontext to the sender. If they match, close the window.

Simple, and keeps your view abstracted from your viewmodel.

Here would be my approach using MVVM-light toolkit:

In the ViewModel:

public void notifyWindowToClose()
{
    Messenger.Default.Send<NotificationMessage>(
            new NotificationMessage(this, "CloseWindowsBoundToMe")
                );
                }
                

And in the View:

Messenger.Default.Register<NotificationMessage>(this, (nm) =>
{
    if (nm.Notification == "CloseWindowsBoundToMe")
        {
                if (nm.Sender == this.DataContext)
                            this.Close();
                                }
                                });
                                
-------------------

I used to use the dialogcloser attached behavior, but i find the below solution easier where I can use it. The sample below takes an example of a close button on the window for simplicity.

pass the window as the command parameter.

in the button xaml for the view:

CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"

in the command execute method in the view model:

if (parameter is System.Windows.Window)
{
    (parameter as System.Windows.Window).Close();
    }
    
-------------------

Generally you would use some kind of controller/presenter/service to drive the screen activation/deactivation. MVVM is not meant to be the One Pattern to Rule Them All. You will need to combine it with other patterns in any non-trivial application.

That said, in some situations in makes sense to have a view model that manages the life cycle of child view models. For example, you might have an EditorViewModel that manages a collection of child view models - one for each document being edited. In that case, simply adding/removing to/from this collection can result in the view activating/deactivating. But this does not sound like it fits your use case.

-------------------

http://adammills.wordpress.com/2009/07/01/window-close-from-xaml/

<Style.Triggers> <DataTrigger Binding="{Binding CloseSignal}" Value="true"> <Setter Property="Behaviours:WindowCloseBehaviour.Close" Value="true" /> </DataTrigger> </Style>

-------------------

You can make a command that attaches to the window and when executed closes the window. Then you can bind that command to a property on your view model, and execute the command when you want to close the window.

-------------------

I would use an ApplicationController which instantiates the LoginViewModel and shows the LoginView. When the user proceeds with the login screen the ApplicationController closes the LoginView and shows the MainView with its MainViewModel.

How this can be done is shown in the sample applications of the WPF Application Framework (WAF) project.

-------------------

This answer shows another way to do this:

How should the ViewModel close the form?

It uses an attached property to bind the DialogResult window property to a ViewModel property. When setting the value of DialogResult to true or false, the view is closed.

-------------------

Just close in an EventHandler in code behind and handle everything else in the view model where you can use a command binding.

-------------------

You can also do this using event. Though you need like 3 lines of codes in your view code behind (some MVVM purist don't like this);

In your viewmodel, you create an event that the view can subscribe to:

    public event CloseEventHandler Closing;
    public delegate void CloseEventHandler();
        private void RaiseClose()
            {
                    if (Closing != null)
                                Closing();
                                    }
                                    

In your, view you subscribe to the event after your initializecomponent method as below:

        public View
        {
                   *//The event can be put in an interface to avoid direct dependence of the view on the viewmodel. So below becomes
                               //ICloseView model = (ICloseView)this.DataContext;*
                                           ProgressWindowViewModel model = (ProgressWindowViewModel)this.DataContext;
                                                       model.Closing += Model_Closing;
                                                               }
                                                                       private void Model_Closing()
                                                                               {
                                                                                            this.Close();
                                                                                                    }
                                                                                                    

You just simply call RaiseClose() when you are ready to close the View from the ViewModel.

You can even use this method to send message to the view from the viewmodel.

The event can be put in an interface to avoid direct dependence of the view on the viewmodel.

-------------------

viewmodel에서보기를 닫으려면 Galasoft MVVM Light Toolkit을 사용했습니다. 여기에서 다운로드 할 수 있습니다. http://www.mvvmlight.net/

  1. 다음과 같은 클래스를 만듭니다. public class ClosingRequested : MessageBase {}

  2. 뷰 생성자에 다음을 추가합니다. Messenger.Default.Register (this, vm, msg => Close ());

  3. 창을 닫으려면 다음을 호출하십시오. Messenger.Default.Send (new ClosingRequested (), this);



출처
https://stackoverflow.com/questions/1902764
댓글
공지사항
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31