WPF Prism中View输入数据无法传递至ViewModel,命令未触发
问题:Prism框架下ViewModel未实例化导致命令绑定失效
问题描述
在WPF项目中使用Prism框架,尝试将View输入字段的数据传递至ViewModel以实现新增用户到数据库的功能。已为按钮绑定AddUserCommand,但ViewModel未被调用,调试发现程序甚至未进入ViewModel的构造函数。IntelliSense未显示绑定错误,命名空间也正确。
相关代码
按钮命令绑定代码
<Button IsDefault="True" Content="Зберегти" Command="{Binding AddUserCommand}">
View的XAML代码
<Window x:Class="EmployeeDirectoryWPF.View.AddWindow" ... xmlns:vm="clr-namespace:EmployeeDirectoryWPF.ViewModel" mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" d:DataContext="{d:DesignInstance Type=vm:AddViewModel}" WindowStyle="ToolWindow" ResizeMode="CanResizeWithGrip" WindowStartupLocation="CenterOwner" SizeToContent="WidthAndHeight"> <TextBlock Grid.Row="1" Grid.Column="0" Text="Ім'я:" /> <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Name, Mode=TwoWay}" /> <StackPanel Grid.Row="10" Grid.Column="1" HorizontalAlignment="Center" Orientation="Horizontal" Margin="0,20"> <Button IsDefault="True" Content="Зберегти" Command="{Binding AddUserCommand}" Margin="0,0,25,0" /> </StackPanel> </Grid> </Window>
ViewModel代码
namespace EmployeeDirectoryWPF.ViewModel; public class AddViewModel : BindableBase { private Employee _newEmployee; private ObservableCollection<Employee> _employees; private MyDbContext _db; public Employee NewEmployee { get => _newEmployee; set => SetProperty(ref _newEmployee, value); } private bool _isEnabled; public bool IsEnabled { get { return _isEnabled; } set { SetProperty(ref _isEnabled, value); } } public DelegateCommand AddUserCommand { get; private set; } public AddViewModel(ObservableCollection<Employee> employees, MyDbContext db) { _employees = employees; _newEmployee = new Employee(); _db = db; AddUserCommand = new DelegateCommand(AddNewEmployee) .ObservesCanExecute(() => IsEnabled); } private void AddNewEmployee() { try { if (!CanAddNewEmployee()) { return; } _employees.Add(new Employee { Name = _newEmployee.Name, DateOfBirth = _newEmployee.DateOfBirth, }); _db.SaveChanges(); NewEmployee = new Employee(); } catch (Exception ex) { // 建议添加异常处理逻辑 } } private bool CanAddNewEmployee() { // 补充该方法的实现逻辑,比如校验输入合法性 return !string.IsNullOrEmpty(_newEmployee.Name); } }
解决建议
启用Prism的ViewModelLocator自动绑定
在App.xaml中确保配置ViewModelLocator,且App类继承自PrismApplication:<prism:PrismApplication x:Class="EmployeeDirectoryWPF.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:prism="http://prismlibrary.com/"> <prism:PrismApplication.Resources> <ResourceDictionary> <prism:ViewModelLocator.AutoWireViewModel>True</prism:ViewModelLocator.AutoWireViewModel> </ResourceDictionary> </prism:PrismApplication.Resources> </prism:PrismApplication>配置依赖注入容器
由于AddViewModel构造函数依赖ObservableCollection<Employee>和MyDbContext,需在App.xaml.cs的RegisterTypes方法中注册这些依赖:protected override void RegisterTypes(IContainerRegistry containerRegistry) { containerRegistry.RegisterSingleton<MyDbContext>(); // 按需注册ObservableCollection,若需全局共享则注册为单例 containerRegistry.RegisterInstance(new ObservableCollection<Employee>()); // 手动注册视图与ViewModel的导航关联(自动绑定失效时使用) containerRegistry.RegisterForNavigation<AddWindow, AddViewModel>(); }使用Prism服务打开窗口
避免直接new AddWindow(),改用Prism的IDialogService或IRegionManager打开窗口,确保ViewModel被容器正确实例化并注入依赖:// 示例:使用IDialogService打开弹窗 var parameters = new DialogParameters(); _dialogService.ShowDialog(nameof(AddWindow), parameters, result => { // 处理窗口关闭后的逻辑 });修正数据绑定路径
当前TextBox绑定的Name在ViewModel中无直接属性,需修正为绑定NewEmployee.Name:<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding NewEmployee.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />补全ViewModel缺失逻辑
补充_db字段声明和CanAddNewEmployee方法的校验逻辑,确保命令执行的合法性判断生效。
内容的提问来源于stack exchange,提问作者Максим Николаевич
相关产品推荐
相关产品推荐

