简体   繁体   English

从另一个视图更改ContentControl的内容

[英]Changing ContentControl's Content from another view

I have question how to control views in content control. 我对如何在内容控制中控制视图有疑问。 I have two views where are buttons and I want that click in one of this buttons will occur change of view to second. 我有两个视图,其中的按钮位于其中,我希望单击其中一个按钮会发生视图更改为第二个的情况。 I'm using MVVM and my problem is that I don't know how change ViewModel binded to ContentControl. 我正在使用MVVM,我的问题是我不知道如何将ViewModel绑定到ContentControl。 Maybe my code tell you more than I can clarify: 也许我的代码告诉了您很多我无法澄清的事情:

// Main window view
<Window x:Class="ContentControlTestApp.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525"
    DataContext="{Binding Main, Source={StaticResource Locator}}">
    <Grid>
        <ContentControl Content="{Binding CurrentViewModel}"/>
    </Grid>
</Window>
// Main window view model
public class MainViewModel : ViewModelBase
{
    private ViewModelBase _currentViewModel;

    public ViewModelBase CurrentViewModel
    {
        get { return _currentViewModel; }
        set
        {
            _currentViewModel = value; 
            RaisePropertyChanged("CurrentViewModel");
        }
    }
    private ViewModelLocator Locator
    {
        get
        {
            return App.Current.Resources["Locator"] as ViewModelLocator;
        }
    }

    public MainViewModel()
    {
        CurrentViewModel = Locator.FirstControl;
    }
}

//App.xaml
<Application x:Class="ContentControlTestApp.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="MainWindow.xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" d1p1:Ignorable="d" xmlns:d1p1="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:vm="clr-namespace:ContentControlTestApp.ViewModel" xmlns:view="clr-namespace:ContentControlTestApp.View">
<Application.Resources>
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
  <DataTemplate DataType="{x:Type vm:FirstControlViewModel}">
      <view:FirstControlView></view:FirstControlView>
  </DataTemplate>
    <DataTemplate DataType="{x:Type vm:SecondControlViewModel}">
        <view:SecondControlView></view:SecondControlView>
    </DataTemplate>
</Application.Resources>
</Application>

//First Control View
<UserControl x:Class="ContentControlTestApp.View.FirstControlView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid>
    <StackPanel>
        <Label Content="First Control" />
        <Button Content="Switch to second control" Command="{Binding SwitchToSecondControlCommand}"/>
    </StackPanel>
</Grid>
</UserControl>

//First Control view model
public class FirstControlViewModel:ViewModelBase
{
    private RelayCommand _switchToSecondControlCommand;

    public ICommand SwitchToSecondControlCommand
    {
        get
        {
            return _switchToSecondControlCommand ??
                   (_switchToSecondControlCommand = new RelayCommand(SwitchToSecondControlExecute));
        }
    }

    private void SwitchToSecondControlExecute()
    {
        //I don't know what to do here
    }
}

//Second Control View
<UserControl x:Class="ContentControlTestApp.View.SecondControlView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid>
    <StackPanel>
        <Label Content="Second Control" />
        <Button Content="Switch to first control" Command="{Binding SwitchToFirstControlCommand}"/>
    </StackPanel>
</Grid>
</UserControl>

//Second Control view model
public class SecondControlViewModel:ViewModelBase
{
    private RelayCommand _switchToFirstControlCommand;

    public ICommand SwitchToFirstControlCommand
    {
        get
        {
            return _switchToFirstControlCommand ??
                   (_switchToFirstControlCommand = new RelayCommand(SwitchToSecondControlExecute));
        }
    }

    private void SwitchToSecondControlExecute()
    {
        //I don't know what to do here
    } 
}

//ViewModelLocator
public class ViewModelLocator
{
    public ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

        SimpleIoc.Default.Register<MainViewModel>();
        SimpleIoc.Default.Register<FirstControlViewModel>();
        SimpleIoc.Default.Register<SecondControlViewModel>();
    }

    public MainViewModel Main
    {
        get
        {
            return ServiceLocator.Current.GetInstance<MainViewModel>();
        }
    }

    public FirstControlViewModel FirstControl
    {
        get { return ServiceLocator.Current.GetInstance<FirstControlViewModel>(); }
    }

    public SecondControlViewModel SecondControl
    {
        get { return ServiceLocator.Current.GetInstance<SecondControlViewModel>(); }
    }

    public static void Cleanup()
    {
        // TODO Clear the ViewModels
    }
}

And I don't know how change CurrentViewModel in MainViewModel from for example FirstControlViewModel's command. 而且我不知道如何从例如FirstControlViewModel的命令更改MainViewModel中的CurrentViewModel。 Any idea? 任何想法? I thought about some event but this looks not good. 我想到了一些事情,但这看起来并不好。 Does anyone have any idea? 有人有什么主意吗?

Thanks 谢谢

First things first... to change the view, we change the view model (assuming that you have correctly declared a DataTemplate for it): 首先要做的是...要更改视图,我们更改视图模型(假设您已正确为其声明了DataTemplate ):

<ContentControl Content="{Binding CurrentViewModel}"/>

... ...

CurrentViewModel = new OtherViewModel();

Clearly, you can only do that from your MainViewModel . 显然,您只能从MainViewModel执行此操作。 Therefore, you should handle the Button ICommand in your MainViewModel , so move your SwitchToFirstControlCommand there and change your Button.Command Binding Path to this: 因此,您应该MainViewModel处理Button ICommand ,因此将SwitchToFirstControlCommand那里,并将Button.Command Binding Path更改为:

<Button Content="Switch to first control" Command="{Binding DataContext.
    SwitchToFirstControlCommand, RelativeSource={RelativeSource 
    AncestorType={x:Type MainWindow}}}" />

Now in your main view model: 现在在您的主视图模型中:

private void SwitchToSecondControlExecute()
{
    CurrentViewModel = new OtherViewModel();
}    

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM