2012-06-15 33 views
4

我有一個窗口,它承載各種用戶控件的頁面。是否可以在usercontrol的datacontext中關閉我沒有提及的窗口? 簡化的細節:如何從其用戶控件視圖模型關閉窗口?

SetupWindow

public SetupWindow() 
    { 
     InitializeComponent(); 
     Switcher.SetupWindow = this; 
     Switcher.Switch(new SetupStart()); 
    } 

    public void Navigate(UserControl nextPage) 
    { 
     this.Content = nextPage; 
    } 

SetupStart用戶控件

<UserControl x:Class="..."> 
<UserControl.DataContext> 
    <local:SetupStartViewModel/> 
</UserControl.DataContext> 
<Grid> 
    <Button Content="Continue" Command="{Binding ContinueCommand}"/> 
</Grid> 
</UserControl> 

SetupStartViewModel

public SetupStartViewModel() 
    { 
    } 

    private bool canContinueCommandExecute() { return true; } 

    private void continueCommandExectue() 
    { 
     Switcher.Switch(new SetupFinish()); 
    } 

    public ICommand ContinueCommand 
    { 
     get { return new RelayCommand(continueCommandExectue, canContinueCommandExecute); } 
    } 
+0

問題可能重複http://stackoverflow.com /問題/ 1484233/WPF的MVVM閉-A-視圖從 - 視圖模型。 – 2012-06-15 10:24:05

+0

非常好的問題,真的。 – Vlad

回答

5

我設法找到一個答案在這裏的解決方案:How to bind Close command to a button

視圖模型:

public ICommand CloseCommand 
{ 
    get { return new RelayCommand<object>((o) => ((Window)o).Close(), (o) => true); } 
} 

查看:

<Button Command="{Binding CloseCommand}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" Content="Close"/> 
3

內,您的用戶控件,你可以找到一個與託管它的窗口的引用窗口上的靜態方法c姑娘。

var targetWindow = Window.GetWindow(this); 
targetWindow.Close(); 

編輯:

如果你有沒有提到該數據上下文你正在使用沒有一個龐大的選擇量,如果只是1個應用程序窗口的用戶控件你可以逃脫

Application.Current.MainWindow.Close() 

如果有多個窗口在您的應用程序和一個要關閉的焦點,你可以找到的東西,如

public Window GetFocusWindow() 
{ 
    Window results = null; 
    for (int i = 0; i < Application.Current.Windows.Count; i ++) 
     if (Application.Current.Windows[i].IsFocused) 
     { 
      results = Application.Current.Windows[i]; 
      break; 
     } 
    return results; 
} 

最後我想(雖然這很漂亮),你可以遍歷應用程序窗口類,檢查視覺樹中每個對象的數據上下文,直到找到你想要的引用,窗口可以是從那裏關閉。

+1

我通常最終會在視圖模型,RequestClose或類似的東西中編寫我自己的事件,用戶控件會監聽這些事件。然後它關閉事件的窗口。只是爲了避免將用戶控件/窗口引用傳遞給視圖模型。 :) –

+1

這不是我的問題的答案,我知道如何在代碼隱藏 – user13070

+0

@ user13070中執行此操作然後創建事件並在需要關閉窗口時將其提升。然後在偵聽所述事件的方法中從代碼隱藏中關閉它。 :)當然,這需要你連接事件,最好在控件的構造函數中。但我沒有更好的主意。 –

5

我這樣做是通過在ViewModel中有一個RequestClose事件來實現的,它可以在視圖關閉時引發。

然後通過創建窗口的代碼連接到窗口的Close()命令。例如

var window = new Window(); 
var viewModel = new MyViewModel(); 

window.Content = viewModel; 
viewModel.RequestClose += window.Close; 

window.Show() 

這樣所有的窗口創建工作都在一個地方進行。視圖或視圖模型都不知道窗口。

+0

我的窗口沒有編程創建,我沒有提及它,因爲我提到 – user13070

+0

東西必須創建窗口。那應該是控制窗口壽命。您的UserControl不應該瞭解Windows,它甚至可能不在窗口中託管。 – GazTheDestroyer

+0

是的,我弄錯了,不知道我的意思。但是我可以添加此事件,但是如何從我的視圖模型(這是用戶控件的後面)觸發該事件 – user13070