从另一个视图更改ContentControl's内容

本文关键字:内容 ContentControl 另一个 视图 | 更新日期: 2023-09-27 18:17:11

我对如何在内容控制中控制视图有疑问。我有两个视图,其中有按钮,我希望点击其中一个按钮会发生视图切换到第二。我使用MVVM和我的问题是,我不知道如何改变ViewModel绑定到ContentControl。也许我的代码告诉你的比我能说清楚的更多:

// 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
    }
}

我不知道如何改变CurrentViewModel在MainViewModel例如FirstControlViewModel的命令。任何想法?我考虑过一些事件,但这看起来不太好。有人知道吗?

谢谢

从另一个视图更改ContentControl's内容

重要的事情先说…要更改视图,我们更改视图模型(假设您已经为其正确声明了DataTemplate):

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

CurrentViewModel = new OtherViewModel();

显然,您只能从您的MainViewModel中做到这一点。因此,您应该在MainViewModel 中处理Button ICommand ,因此将SwitchToFirstControlCommand移到那里并将Button.Command Binding Path更改为:

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

现在在你的主视图模型中:

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