如何在应用程序启动时初始化viewmodel的datacontext?

时间:2017-06-14 17:56:35

标签: wpf mvvm mvvm-light

我最近开始使用MVVMLight框架。

当我使用ContentPresenter在ViewModel之间切换时,它似乎在首次显示时初始化datacontext。

但是,我希望它初始化它的datacontext,以便它可以跟踪应用程序初始加载的任何变化,或者至少与其他viewmodel共享数据(我假设我可以使用dataservice来跟踪所有数据,但我找不到与contentpresenter& MVVMLight一起使用的正确示例。

以下是我制作的示例代码。当我点击Review按钮时,“usercontrolview”将显示“Picture Saved”,但“contentpresenterview”将显示“No Picture”。

Sample Image

MainView.xaml

<Grid>
    <Button x:Name="CaptureButton" Content="Capture" HorizontalAlignment="Left" Margin="34,10,0,0" VerticalAlignment="Top" Width="75"
            Command="{Binding CaptureCommand}"/>
    <Button x:Name="ReviewButton" Content="Review" HorizontalAlignment="Left" Margin="146,10,0,0" VerticalAlignment="Top" Width="75"
            Command="{Binding ShowReviewCommand}"/>
    <TextBlock FontSize="36"
               FontWeight="Bold"
               Foreground="Purple"
               Text="{Binding CaptureStatus}"
               VerticalAlignment="Center"
               HorizontalAlignment="Center"
               TextWrapping="Wrap" />

    <Grid x:Name="usercontrolview" Visibility="{Binding ReviewModeOn, Converter={StaticResource BooleanToVisibilityConverter}}" Margin="0,50,150,0">
        <view:ReviewView/>
    </Grid>
    <ContentPresenter x:Name="contentpresenterview" Content="{Binding CurrentContent}" Margin="150,50,0,0"/>
</Grid>

MainViewModel.cs(Partial)

public MainViewModel()
    {
        CaptureStatus = "No Picture";

        CaptureCommand = new RelayCommand(Capture);
        ShowReviewCommand = new RelayCommand(ShowReview);

        ReviewModeOn = false;
    }


    public RelayCommand CaptureCommand { get; private set; }
    private void Capture()
    {
        CaptureStatus = "Pictures Saved";
        Messenger.Default.Send<NotificationMessage>(new NotificationMessage("Pictures Saved"), "Captured");
    }
    public RelayCommand ShowReviewCommand { get; private set; }
    private void ShowReview()
    {
        ReviewModeOn = !ReviewModeOn;
        CurrentContent = ContentViewModel;
    }

我的ReviewViewModel&amp;的模板ReviewContentPresenterViewModel

    public ***ViewModel()
    {
        Messenger.Default.Register<NotificationMessage>(this, "Captured", Captured);

        CaptureStatus = "No Picture";
    }

    private void Captured(NotificationMessage notificationMessage)
    {
        CaptureStatus = notificationMessage.Notification;
    }

    private string _captureStatus;
    public string CaptureStatus
    {
        get { return _captureStatus; }
        set { Set(ref _captureStatus, value); }
    }

=======================更新=======================

我的ReviewView&amp;的模板ReviewContentPresenterView。 它需要定位器的DataContext。

<UserControl x:Class="***View"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:ignore="http://www.galasoft.ch/ignore"
    mc:Ignorable="d ignore"
    DataContext="{Binding ***ViewModel, Source={StaticResource Locator}}">

    <Grid Background="Gray">
        <TextBlock FontSize="36"
               FontWeight="Bold"
               Foreground="Purple"
               Text="{Binding CaptureStatus}"
               VerticalAlignment="Center"
               HorizontalAlignment="Center"
               TextWrapping="Wrap" />
    </Grid>
</UserControl>

1 个答案:

答案 0 :(得分:0)

看起来根网格中的DataContext及其所有子节点是MainViewModel,并且您需要ContentPresenter的其他DataContext。创建另一个ViewModel作为资源,例如

<Grid>
<Grid.Resources>
    <local:TheViewModelIWant x:Key=ContentViewModel/>      
</Grid.Resources>
...
...
<ContentPresenter DataContext={StaticResource ContentViewModel} ...

(顺便说一句,如果您已经在某处创建了一个TheViewModelIWant实例,例如在其他ViewModel或后面的视图代码中,那么您可以停止使用该实例并以C#代码访问此实例Resources["ContentViewModel"]