2016-11-24 127 views
1

如何將窗口設置爲從ViewModel聲明,初始化並打開的所有者?如何從WPF中的ViewModel設置窗口作爲所有者窗口

下面是代碼:

public class ViewModel : INotifyPropertyChanged 

{ 
    // declaration 
    static nextWindow nw; 
    ... 

    public ICommand OpenNextWindow { get { return new RelayCommand(OpenNextWindowExecute, CanOpenNextWindowExecute); } } 

    bool CanOpenNextWindowExecute(object parameter) 
    { 
     return true; 
    } 

    void OpenNextWindowExecute(object parameter) 
    { 
     nw = new nextWindow(); 
     nw.WindowStartupLocation = WindowStartupLocation.CenterScreen; 
     // Set this window as owner before showing it... 
     nw.Show(); 
    } 
} 

在代碼隱藏文件NextWindow的,我可以用這個代碼集NextWindow的爲業主:

nw.Owner = this; 

如何從視圖模型實現的呢?

+0

你可以嘗試結合它到您ViewModel中的一個Window,並且從您VM中將Window設置爲任何相關的。 但是,你通常希望你ViewModel不知道你的視圖,所以我不知道這將是一個乾淨的方式。 – Belterius

回答

3

說實話,我不會做任何與在ViewModel中顯示窗口有關的東西。你可以做的事情是發送一條消息(例如使用MVVMLight的Messenger服務)到視圖,在那裏你可以做顯示和設置所有者shinanigaz

1

MVVM背後的全部想法是,你想要一個乾淨的分離視圖和業務邏輯,從而實現更好的維護,可伸縮性和測試等。因此,您的視圖模型應該總是不知道任何視圖的存在。

因此利用其觀點信使服務或一些視圖處理程序中可以聽,然後決定是否要處理的消息,或者沒有。這樣,視圖處理程序就可以決定下一個要調用哪個視圖或顯示哪個消息框。

有很多可用的選項,但作爲@Oyiwai說MVVMLight的Messenger服務是一種快捷易用。

在您的軟件包管理器控制檯中運行install-package MvvmLightLibs。 MvvmLightLibs還有一個額外的好處,就是它已經實現了INotifyPropertyChanged,我看到了你的實現。

注意這是一個簡單的例子。我不建議使用case語句,因爲我在這裏使用哪個硬編碼查看名稱。

創建WindowMessage類..

public class RaiseWindowMessage 
{ 
    public string WindowName { get; set; } 
    public bool ShowAsDialog { get; set; } 
} 

在您的視圖模型

public class ViewModel : ViewModelBase 
{ 
    public RelayCommand<string> RaiseWindow => new RelayCommand<string>(raiseWindow, canRaiseWindow); 

    private bool canRaiseWindow(string nextWindowName) 
    { 
     // some logic 
     return true; 
    } 

    private void raiseWindow(string nextWindowName) 
    { 
     RaiseWindowMessage message = new RaiseWindowMessage(); 
     message.WindowName = nextWindowName; 
     message.ShowAsDialog = true; 

     MessengerInstance.Send<RaiseWindowMessage>(message); 
    } 
} 

您認爲或最好在一些視圖處理程序類..

public class ViewHandler 
{ 
    public ViewHandler() 
    { 
     Messenger.Default.Register<RaiseWindowMessage>(this, raiseNextWindow); 
    }   

    private void raiseNextWindow(RaiseWindowMessage obj) 
    { 
     // determine which window to raise and show it 
     switch (obj.WindowName) 
     { 
      case "NextWindow": 
       NextWindow view = new NextWindow(); 
       if (obj.ShowAsDialog) 
        view.ShowDialog(); 
       else 
        view.Show(); 
       break; 
      // some other case here... 
      default: 
       break; 
     } 
    } 
}