You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);
    }
}

解决建议

  1. 启用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>
    
  2. 配置依赖注入容器
    由于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>();
    }
    
  3. 使用Prism服务打开窗口
    避免直接new AddWindow(),改用Prism的IDialogService或IRegionManager打开窗口,确保ViewModel被容器正确实例化并注入依赖:

    // 示例:使用IDialogService打开弹窗
    var parameters = new DialogParameters();
    _dialogService.ShowDialog(nameof(AddWindow), parameters, result =>
    {
        // 处理窗口关闭后的逻辑
    });
    
  4. 修正数据绑定路径
    当前TextBox绑定的Name在ViewModel中无直接属性,需修正为绑定NewEmployee.Name:

    <TextBox Grid.Row="1" Grid.Column="1" 
             Text="{Binding NewEmployee.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
    
  5. 补全ViewModel缺失逻辑
    补充_db字段声明和CanAddNewEmployee方法的校验逻辑,确保命令执行的合法性判断生效。

内容的提问来源于stack exchange,提问作者Максим Николаевич

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 16:14:51