WPF窗口上的Closing-EventTrigger - DataContext的问题

时间:2013-11-06 11:03:43

标签: wpf

我有一个视图,它初始化windows资源中的视图模型。更进一步,我给我的网格DataContext。

我的问题是,我如何在Windows关闭事件中添加命令,将mvvm保留在内存中?我试过这篇文章的版本: Handling the window closing event with WPF / MVVM Light Toolkit ...但它无法使用事件触发器,因为我无法从网格外部访问viewmodel,因此无法访问我的命令。

我的问题的任何解决方案?

问候

Jannik

编辑:这是我的xaml:

<Window x:Class="WpfApplication1.Views.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:viewModels="clr-namespace:WpfApplication1.ViewModels"
    xmlns:converter="clr-namespace:WpfApplication1.Converter"
    Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <viewModels:MainWindowViewModel x:Key="ViewModel"/>
    </Window.Resources>

    <Grid DataContext="{StaticResource ViewModel}">...</Grid>
</Window>

2 个答案:

答案 0 :(得分:1)

您可以通过以下方式引用静态资源的成员:

Command="{Binding Path=CloseCommand, Source={StaticResource ViewModel}}"

这是完整的测试项目。我使用带有绑定的文本框来确保保存数据。

<Window x:Class="WpfApplication1.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:viewModels="clr-namespace:WpfApplication1.ViewModels"
        xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <viewModels:MainWindowViewModel x:Key="ViewModel"/>
    </Window.Resources>

    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Closing">
            <i:InvokeCommandAction Command="{Binding Path=CloseCommand, Source={StaticResource ViewModel}}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
    <Grid DataContext="{StaticResource ViewModel}">
        <TextBox Text="{Binding Txt, UpdateSourceTrigger=PropertyChanged}"/>
    </Grid>
</Window>

在ViewModel代码中,我使用静态引用来存储数据(LastInstance)。你可以用自己的方法替换它。

我还使用Command这是ICommand的自定义实现。如果您愿意,我可以在这里添加完整的实现。

    public MainWindowViewModel()
    {
        //save or load here...
        if (LastInstance != null) Txt = LastInstance.Txt;
        CloseCommand = new Command(o => LastInstance = this);
        //...
    }

    public static ViewModel LastInstance;

    //Txt Dependency Property
    public string Txt
    {
        get { return (string)GetValue(TxtProperty); }
        set { SetValue(TxtProperty, value); }
    }
    public static readonly DependencyProperty TxtProperty =
        DependencyProperty.Register("Txt", typeof(string), typeof(ViewModel), new UIPropertyMetadata(null));
    //CloseCommand Dependency Property
    public Command CloseCommand
    {
        get { return (Command)GetValue(CloseCommandProperty); }
        set { SetValue(CloseCommandProperty, value); }
    }
    public static readonly DependencyProperty CloseCommandProperty =
        DependencyProperty.Register("CloseCommand", typeof(Command), typeof(ViewModel), new UIPropertyMetadata(null));

答案 1 :(得分:0)

解决此问题的典型方法是使用MainViewModel并将Window的DataContext设置为它。然后在MainViewModel中定义其他viewModel。

<Window>
    <Grid DataContext="{Binding MyGridViewModel}">
    </Grid>
    <DockPanel DataContext="{Binding AnotherViewModel}">
    </DockPanel>
</Window>
MainWindow构造函数中的

this.DataContext = new MainViewModel();
MainViewModel构造函数中的

this.MyGridViewModel = new OtherViewModel();

通过这种方式,您可以通过viewModel引用找到所需对象。