gpt4 book ai didi

c# - 将 ContentControl 绑定(bind)到将确定要查看哪个用户控件的 ApplicationViewModel?

转载 作者:太空宇宙 更新时间:2023-11-03 14:56:17 25 4
gpt4 key购买 nike

我是 WPF 的新手,也是 C# 编程(一般编程)的新手,我正在尝试开发 WPF 应用程序。

我已经尝试过几篇与此类似的帖子,但我似乎无法找到为什么这不起作用的答案。

所以,我很难理解 MVVM 架构,它如何以及需要什么来在绑定(bind)到单个 <ContentControl /> 的多个用户控件之间切换.据我目前的理解和阅读,我必须像这样绑定(bind) View 模型:

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

所以这就是我想要实现的目标:

ApplicationWindow.xaml左侧边栏菜单将在应用程序运行时始终显示,以及 <ContentControl/>在剩余空间上。侧边栏菜单上显示的按钮将是:

  • Main(将显示 MainView.xaml 用户控件,应为默认用户控件)
  • 设置(将显示 SettingsView.xaml 用户控制)
  • 退出(将关闭应用程序)

我知道我需要将按钮绑定(bind)到 ICommand命令,我理解 RelayCommand.cs 的概念类(class)。因此,让我们跳入我的想法的简化代码,找出我需要理解的内容以及我在这个过程中可能误解的内容。

什么 MainView.xamlSettingsView.xaml包含现在并不重要,因为我只是想弄清楚如何在我的应用程序中显示它们。

这是 ApplicationWindow.xaml :

<Window x:Class="WpfApp1.ApplicationWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
xmlns:v="clr-namespace:WpfApp1.View"
xmlns:vm="clr-namespace:WpfApp1.ViewModel"
mc:Ignorable="d"
Title="ApplicationWindow" Height="1080" Width="1920"
WindowStyle="None" WindowState="Maximized">

<Window.Resources>
<DataTemplate DataType="{x:Type vm:MainViewModel}">
<v:MainView/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:SettingsViewModel}">
<v:SettingsView/>
</DataTemplate>
</Window.Resources>

<DockPanel>
<!--Menu bar on the left-->
<Border DockPanel.Dock="Left">
<StackPanel Orientation="Vertical" Background="Gray" Width="120">
<Button Content="Main" Command="{Binding ShowMainCommand}"/>
<Button Content="Settings" Command="{Binding ShowSettingsCommand}"/>
<Button Content="Exit" Command="{Binding ExitApplicationCommand}"/>
</StackPanel>
</Border>
<!--The content control that view the current view-->
<ContentControl Content="{Binding ApplicationViewModel}"/>
</DockPanel>
</Window>

注意: DataContext 设置为 ApplicationViewModel.cs在 App.xaml.cs 中重写 OnStartup() 方法。

public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);

ApplicationWindow app = new ApplicationWindow
{
DataContext = new ApplicationViewModel()
};
app.Show();
}
}

这是 ApplicationViewModel.cs :

public class ApplicationViewModel : ViewModelBase
{
#region Fields

private List<ViewModelBase> _viewModels;
private ViewModelBase _currentViewModel;

private ICommand _showMainCommand;
private ICommand _showSettingsCommand;
private ICommand _exitApplicationCommmand;

#endregion

#region Constructor

public ApplicationViewModel()
{
ViewModels = new List<ViewModelBase>
{
new MainViewModel(),
new SettingsViewModel()
};

CurrentViewModel = ViewModels[0];
}

#endregion

#region Public Properties

public List<ViewModelBase> ViewModels
{
get
{
return _viewModels;
}
set
{
if (_viewModels != value)
{
_viewModels = value;
OnPropertyChanged(nameof(ViewModels));
}
}
}

public ViewModelBase CurrentViewModel
{
get
{
return _currentViewModel;
}
set
{
if(_currentViewModel != value)
{
_currentViewModel = value;
OnPropertyChanged(nameof(CurrentViewModel));
}
}
}

#endregion

#region Commands

public ICommand ShowMainCommand
{
get
{
if(_showMainCommand == null)
{
_showMainCommand = new RelayCommand(action => ShowMain());
}
return _showMainCommand;
}
}

public ICommand ShowSettingsCommand
{
get
{
if (_showSettingsCommand == null)
{
_showSettingsCommand = new RelayCommand(action => ShowSettings());
}
return _showSettingsCommand;
}
}

public ICommand ExitApplicationCommand
{
get
{
if (_exitApplicationCommmand == null)
{
_exitApplicationCommmand = new RelayCommand(action => ExitApplication());
}
return _exitApplicationCommmand;
}
}

#endregion

#region Private Methods

private void ShowMain()
{
CurrentViewModel = ViewModels[0];
}

private void ShowSettings()
{
CurrentViewModel = ViewModels[1];
}

private void ExitApplication()
{
MessageBoxResult result = MessageBox.Show("Are you sure you want to exit?", "Exit", MessageBoxButton.YesNo);
if (result == MessageBoxResult.Yes)
{
System.Windows.Application.Current.Shutdown();
}
}

#endregion
}

因此,据我了解,ApplicationWindow.xaml应该能够确定从 CurrentViewModel 中显示哪个 View 设置为。

为了提供信息(或遗漏信息),这里有 ViewModelBase.cs :

public class ViewModelBase : INotifyPropertyChanged
{
#region INotifyPropertyChanged

public event PropertyChangedEventHandler PropertyChanged;

protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

#endregion
}

RelayCommand.cs :

public class RelayCommand : ICommand
{
#region Fields

private readonly Action<object> _execute;
private readonly Predicate<object> _canExecute;

#endregion

#region Constructors

public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");

_execute = execute;
_canExecute = canExecute;
}

public RelayCommand(Action<object> execute) : this(execute, null)
{
}

#endregion

#region ICommand

public bool CanExecute(object parameters)
{
return _canExecute == null ? true : _canExecute(parameters);
}

public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}

public void Execute(object parameters)
{
_execute(parameters);
}

#endregion
}

我希望您清楚我在这方面的思考过程,并且你们中的一位聪明的程序员可以帮助解决这个问题,并帮助我理解为什么这不是我想要的结果。

如果我尝试做的事情比 Elon Musk 的让生命成为多行星的项目更难,请随时解释原因并建议我更好的方法

最佳答案

您的内容控件绑定(bind)应指向您在切换 ViewModel 时更改的实际属性

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

关于c# - 将 ContentControl 绑定(bind)到将确定要查看哪个用户控件的 ApplicationViewModel?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48875872/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com