CurrentViewModel 属性更改未反映在 ContentControl 中

问题描述 投票:0回答:2

我目前正在构建一个应用程序,用户可以通过一组单选按钮选择不同的页面。当页面处于活动状态时,我希望单选按钮被检查为 true。按下按钮时,将调用我的命令并调用 onpropertychanged 事件,但主窗口中的 ContentControl 将不会显示下一个视图。 我是 WPF 和 Xaml 的新手,并且真的很想弄清楚这一点。

我已在我的 Github 上附加了示例应用程序的链接。

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>
wpf view navigation viewmodel icommand
2个回答
0
投票

您应该将 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 占用所有可用的屏幕空间


0
投票

看起来如果我将 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>
© www.soinside.com 2019 - 2024. All rights reserved.