我目前正在构建一个应用程序,用户可以通过一组单选按钮选择不同的页面。当页面处于活动状态时,我希望单选按钮被检查为 true。按下按钮时,将调用我的命令并调用 onpropertychanged 事件,但主窗口中的 ContentControl 将不会显示下一个视图。 我是 WPF 和 Xaml 的新手,并且真的很想弄清楚这一点。
我已在我的 Github 上附加了示例应用程序的链接。
public class ApplicationViewModel : ObservableObject
{
private ICommand _changeViewCommand;
private IViewModel _CurrentViewModel;
private List<IViewModel> _viewModels;
private bool _isActive;
public ApplicationViewModel()
{
ViewModels.Add(new HomeViewModel());
ViewModels.Add(new AccountViewModel());
CurrentViewModel = ViewModels.Find(r => r.Name == "Home");
CurrentViewModel.IsActive = true;
}
public List<IViewModel> ViewModels
{
get
{
if (_viewModels == null)
_viewModels = new List<IViewModel>();
return _viewModels;
}
}
public IViewModel CurrentViewModel
{
get
{
return _CurrentViewModel;
}
set
{
if (_CurrentViewModel != value)
{
_CurrentViewModel = value;
OnPropertyChanged();
}
}
}
public ICommand ChangePageCommand
{
get
{
if (_changeViewCommand == null)
{
_changeViewCommand = new RelayCommand(
p => ChangeViewModel((IViewModel)p),
p => p is IViewModel);
}
return _changeViewCommand;
}
}
private void ChangeViewModel(IViewModel viewModel)
{
CurrentViewModel = ViewModels.Find(r => r.Name == viewModel.Name);
}
public bool IsActive
{
get
{
return _isActive;
}
set
{
_isActive = value;
OnPropertyChanged("IsActive");
}
}
}
<UserControl.DataContext>
<viewModels:ApplicationViewModel/>
</UserControl.DataContext>
<UserControl.Resources>
<DataTemplate DataType="{x:Type viewModels:ApplicationViewModel}"/>
<DataTemplate DataType="{x:Type viewModels:HomeViewModel}">
<views:HomeView/>
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:AccountViewModel}">
<views:AccountView/>
</DataTemplate>
</UserControl.Resources>
<StackPanel Orientation="Vertical">
<RadioButton Content="Home" IsChecked="{Binding IsActive, Mode=TwoWay}" Command="{Binding DataContext.ChangePageCommand, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
CommandParameter="{Binding }">
<RadioButton.DataContext>
<viewModels:HomeViewModel/>
</RadioButton.DataContext>
</RadioButton>
<RadioButton Content="Account" IsChecked="{Binding IsActive, Mode=TwoWay}" Command="{Binding DataContext.ChangePageCommand, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
CommandParameter="{Binding }">
<RadioButton.DataContext>
<viewModels:AccountViewModel/>
</RadioButton.DataContext>
</RadioButton>
</StackPanel>
您应该将 RadioButtons 连接到列表中的 ViewModels。不要在 xaml 中创建新的视图模型。
并且 CurrentViewModel 可以通过 ContentControl 显示,并使用资源中贴花的模板之一
<UserControl.DataContext>
<viewModels:ApplicationViewModel/>
</UserControl.DataContext>
<UserControl.Resources>
<DataTemplate DataType="{x:Type viewModels:HomeViewModel}">
<views:HomeView/>
</DataTemplate>
<DataTemplate DataType="{x:Type viewModels:AccountViewModel}">
<views:AccountView/>
</DataTemplate>
</UserControl.Resources>
<StackPanel Orientation="Vertical">
<ItemsControl ItemsSource="{Binding ViewModels}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton Content="{Binding Name}"
IsChecked="{Binding IsActive}"
Command="{Binding DataContext.ChangePageCommand, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
CommandParameter="{Binding }">
</RadioButton>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ContentControl Content="{Binding CurrentViewModel}"/>
</StackPanel>
之后,您可能应该将 StackPanel 更改为 Grid 以允许 ContentControl 占用所有可用的屏幕空间
看起来如果我将 AccountViewModel 分配给按钮 DataContext 并将相对源 AncestorType 设置为 x:Type Window,HomeView 上的按钮会将视图切换到 AccountView。
<Button Height="40" Content="Account" Command="{Binding DataContext.ChangePageCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
CommandParameter="{Binding }">
<Button.DataContext>
<viewModels:AccountViewModel/>
</Button.DataContext>
</Button>