我有问题如何控制内容控件中的视图。我有两个视图,其中有按钮,我想在其中一个按钮中点击将发生视图更改为第二个。我正在使用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
}
}
我不知道如何在MainViewModel中更改CurrentViewModel,例如FirstControlViewModel的命令。任何的想法?我想过一些事情,但这看起来并不好。有没有人有任何想法?
由于
答案 0 :(得分:1)
首先要改变视图,我们更改视图模型(假设您已正确声明了DataTemplate
):
<ContentControl Content="{Binding CurrentViewModel}"/>
...
CurrentViewModel = new OtherViewModel();
显然,您只能通过MainViewModel
执行此操作。因此,您应该处理Button ICommand
中的MainViewModel
,然后将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();
}