2011-06-23 48 views
1

我正在顯示一個窗口。實例被創建並在視圖模型中所示(不好的做法,我知道...)使用MVVM從ViewModel單擊OK_Button後,以編程方式關閉窗口

NewWindow form = new NewWindow(); 
form.ShowDialog(); 

在這種形式我有一個OK_button被按下時,它做的東西。這種形式存在一個ViewModel,它具有OK_Button中的OK命令。 在按下按鈕之後,我想從視圖模型中以編程方式關閉該窗體。我怎樣才能做到這一點?

我用WPF

UPDATE

現在讓我們看看有什麼我做錯了:這裏的DataContext事件不會觸發雖然我的窗口與視圖模型顯示!?

所顯示,並從視圖模型必須是封閉的窗口:

public partial class NewSchoolYearWindow : Window 
    { 
     public NewSchoolYearWindow() 
     { 
      InitializeComponent(); 
     } 

     private void Window_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) 
     { 
      NewSchoolYearViewModel vm = (NewSchoolYearViewModel)e.NewValue; 
      vm.CloseNewSchoolYearDialog +=() => this.Close();    
     } 
    } 

爲什麼DataContextChanged僅甚至沒有解僱?

我用這個XAML在我的窗口:

<Window x:Class="TBM.View.NewSchoolYearWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:ViewModel="clr-namespace:TBM.ViewModel" 
     Title="Start a new school year" 
     Height="412" Width="505" 
     WindowStartupLocation="CenterScreen"   
     WindowStyle="ThreeDBorderWindow" 
     ResizeMode="CanResize" DataContextChanged="Window_DataContextChanged"> 
    <Window.Resources> 

     <ViewModel:NewSchoolYearViewModel x:Key="NewSchoolYearViewModelID" /> 

    </Window.Resources> 

    <Grid DataContext="{Binding ., Source={StaticResource NewSchoolYearViewModelID}}" Name="MainGrid"> 
     <TextBlock Height="27" HorizontalAlignment="Left" Margin="68,46,0,0" Name="textBlock1" Text="School year start" VerticalAlignment="Top" Width="98" /> 
     <TextBlock Height="27" HorizontalAlignment="Left" Margin="68,93,0,0" Name="textBlock2" Text="School year end" VerticalAlignment="Top" Width="98" /> 
     <TextBlock Height="27" HorizontalAlignment="Left" Margin="68,169,0,0" Name="textBlock4" Text="Database name:" VerticalAlignment="Top" Width="150" TextAlignment="Left" TextTrimming="CharacterEllipsis" /> 
     <TextBlock Height="27" HorizontalAlignment="Left" Margin="68,215,0,0" Name="textBlock3" Text="Directory:" VerticalAlignment="Top" Width="63" TextAlignment="Left" TextTrimming="CharacterEllipsis" /> 
     <TextBox IsReadOnly="True" Text="{Binding CurrentSchoolYear.Directory}" Height="23" HorizontalAlignment="Left" Margin="172,212,0,0" Name="textBox3" VerticalAlignment="Top" Width="224" /> 
     <Button Command="{Binding OpenNewSchoolYearDialogCommand}" Content="DIR" Height="23" HorizontalAlignment="Right" Margin="0,211,27,0" Name="button1" VerticalAlignment="Top" Width="54" /> 
     <Button Command="{Binding CreateNewSchoolYearCommand}" Content="OK" Height="23" HorizontalAlignment="Left" Margin="381,299,0,0" Name="button2" VerticalAlignment="Top" Width="75" /> 
     <Button Content="Cancel" Height="23" HorizontalAlignment="Left" Margin="300,299,0,0" Name="button3" VerticalAlignment="Top" Width="75" /> 
     <DatePicker Height="25" HorizontalAlignment="Left" Margin="172,42,0,0" SelectedDate="{Binding CurrentSchoolYear.Start}" SelectedDateFormat="Long" VerticalAlignment="Top" Width="175" /> 
     <DatePicker Height="25" HorizontalAlignment="Left" Margin="172,89,0,0" SelectedDate="{Binding CurrentSchoolYear.End}" SelectedDateFormat="Long" VerticalAlignment="Top" Width="175" /> 
     <TextBox Height="23" HorizontalAlignment="Left" Margin="172,166,0,0" Name="textBox1" Text="{Binding CurrentSchoolYear.Name}" VerticalAlignment="Top" Width="175" /> 
    </Grid> 
</Window> 
+0

的WinForms? asp.net? WPF? Silverlight的? –

+0

winforms和asp.net沒有ViewModels和命令。所以它必須是xaml。所以它是WPF :) – msfanboy

+0

ViewModels和Commands是編程模式的工件,它們本質上並不與XAML或WPF相關。這就是說,在給定的可能性中,WPF/Silverlight *是最有可能被使用的地方。 –

回答

1

在視圖模型聲明一個事件:

public event EventHandler<CloseRequestedEventArgs> CloseRequested; 

protected virtual void OnCloseRequested(bool? dialogResult) 
{ 
    var handler = CloseRequested; 
    if (handler != null) 
     handler(this, new CloseRequestedEventArgs(dialogResult)); 
} 

... 

public class CloseRequestedEventargs : EventArgs 
{ 
    private readonly bool? _dialogResult; 

    public CloseRequestedEventargs(bool? dialogResult) 
    { 
     _dialogResult = dialogResult; 
    } 

    public bool DialogResult { get { return _dialogResult; } } 
} 

並在代碼隱藏處理:

var vm = (MyViewModel)DataContext; 
vm.CloseRequested += vm_CloseRequested; 

... 

private void vm_CloseRequested(object sender, CloseRequestedEventArgs e) 
{ 
    if (e.DialogResult.HasValue) 
     this.DialogResult = e.DialogResult; // sets the dialog result AND closes the window 
    else 
     this.Close(); 
} 
+0

我的this.DataContext是NULL,因爲ViewModel是在View實例化之後創建的。所以這不會在這裏工作。 – msfanboy

+0

不知道我明白了什麼問題...只是在創建虛擬機後訂閱事件 –

+0

我無法在Ctor的窗口代碼隱藏中處理此操作:var vm =(MyViewModel)DataContext; vm.CloseRequested + = vm_CloseRequested;因爲DataContext尚未設置。 – msfanboy