从另一个视图更改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的命令。任何想法?我考虑过一些事件,但这看起来不太好。有人知道吗?
谢谢
重要的事情先说…要更改视图,我们更改视图模型(假设您已经为其正确声明了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();
}