WPF文本框绑定(bind)问题

标签 wpf mvvm binding textbox

我有一个 wpf 窗口,用于添加和编辑有关实体的信息。 我正在使用 mvvm 架构和 ADO.Net 实体模型。

屏幕看起来像这样 -

  <!-- EmployeeView -->
  <Window .....DataContext={.....}>

      <WpfToolkit:Datagrid x:Name="dgEmployees"
                           CanUserAddRows="false"
                           ItemSource="{Binding Path=Employees}"
                           ................
                           SelectedItem="{Binding SelectedEmployee}"..>
            <!-3 datagrid template column binding -->              

      </WpfToolkit:Datagrid>

       <TextBox Text="{Binding ElementName=dgEmployees, Path=SelectedEmployee.FirstName}"/>

       <TextBox Text="{Binding ElementName=dgEmployees, Path=SelectedEmployee.LastName}"/>


        <Button Content="Clear" Command="{Binding ClearCommand}"/>
        <Button Content="Save" Command={Binding SaveCommand}">

  </Window>

这里,ClearCommand 将简单地清除文本框,然后保存将添加或编辑记录。我正在 xaml 本身中设置 DataContext 属性。我想将 CodeBehind 保留为空。

View 模型 -

 public class EmployeeViewModel : INotifyProperyChanged
 {
      DatabaseEntities _dbEntities; // Ado.Net Entity model

      RelayCommand _saveCommand, _clearCommand;

      public ObservableCollection<Employee> Employees{get;set;}

      public Employee SelectedEmployee{get; set;}

      public EmployeeViewModel()
      {
           _dbEntities=new DatabaseEntities();
            GetAllEmployees();
      }

      private void GetAllEmployees()
      {
          Employees = new ObservableCollection<Employee>();

          var query = from _e in _dbEntities.Employee
                      select _e;

          foreach(Employee _emp in query)
          {
              Employees.Add(_emp);
          }
      }

      public ICommand SaveCommand
      {
          get
          {
             if(_saveCommand == null)
             {
                 _saveCommand = new RelayCommand(){param => SaveEmployee()};
             }
          }
      }


      public ICommand ClearCommand
      {
          get
          {
             if(_clearCommand == null)
             {
                 _clearCommand = new RelayCommand(){param => Clear()};
             }
          }
      }


      private void Save()
      {
           /*************************Edit****************************/
          // if editing Employee info (this part works fine)


          Employee emp = _dbEntities.Employee.FirstorDefault<Employee>( p => p.EmpID == SelectedEmployee.EmpID);
          if(emp != null)
          {
          .................

          _dbEntities.SaveChanges(true);
           /************************************************************/
           }
           else
           {
           /*******************Add New**************************/
         // if adding new employee info (doesn't work)

         Employee emp = Employee.CreateEmployee(0, SelectedEmployee.FirstName, SelectedEmployee.LastName); // here NullReference Exception is thrown because SelectedEmployee is null while adding a new Employee. 

         _dbEntities.AddToEmployee(emp
         _dbEntities.SaveChanges(true);

          GetAllEmployees();
         /************************************************************/

         }

      }


      private void Clear()
      {
          // to clear all the textboxes before adding new employee info.
          SelectedEmployee = null;
          OnPropertyChanged("SelectedEmployee");
      }
 }

我可以编辑信息,但不能添加新信息。如果我想添加新的员工信息,请在相应的文本框中输入名字姓氏。这些输入的值不会与 SelectedEmployee 属性绑定(bind),因为 SelectedEmployee 为 null(我们清除字段以添加新记录)。如何从 SelectedEmployee 属性访问文本框中输入的值?

我知道这个问题可以通过使用 IsSelected 属性创建一个单独的 EmployeeModel 来解决......但是还有其他方法吗?

最佳答案

我建议您将 FirstName 和 LastName 放入 ViewModel 上的字符串中,然后您始终可以在 Save 方法中访问它们,无论 SelectedEmployee 是否为 null。

(在您的 Save 方法中)

Employee emp = Employee.CreateEmployee(0, FirstName, LastName);

如果您希望用户更改数据网格中的所选项目时刷新文本框,则需要覆盖 SelectedEmployee 上的 setter ,如下所示:

    string _firstName;
    public string FirstName 
    {
        get { return _firstName; }
        set
        {
            if (_firstName != value)
            {
                _firstName = value;
                OnPropertyChanged("FirstName");
            }
        }
    }

    string _lastName;
    public string LastName
    {
        get { return _lastName; }
        set
        {
            if (_lastName != value)
            {
                _lastName = value;
                OnPropertyChanged("LastName");
            }
        }
    }

    Employee _selectedEmployee;
    public Employee SelectedEmployee
    {
        get { return _selectedEmployee; }
        set
        {
            if (_selectedEmployee != value)
            {
                _selectedEmployee = value;
                OnPropertyChanged("SelectedEmployee");
                FirstName = (_selectedEmployee == null) ? string.Empty : _selectedEmployee.FirstName;
                LastName = (_selectedEmployee == null) ? string.Empty : _selectedEmployee.LastName;
            }
        }
    }

然后只需将您的 xaml 更新为如下所示:

   <TextBox Text="{Binding Path=FirstName}"/>
   <TextBox Text="{Binding Path=LastName}"/>

希望这有帮助:)

关于WPF文本框绑定(bind)问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1798333/

相关文章:

wpf - 将组合框 SelectedValue 绑定(bind)到文本框

WPF如何在列表框失去焦点时更改列表框所选项目的文本颜色

c# - 如何最好地应用WPF MVVM?

text - UWP 中 'TextBlock' 的绑定(bind)部分

java - jOOQ - 多重绑定(bind)

c# - 如何将绑定(bind)重定向到 XAML 控件的 "outside"

带有自定义镶边的 WPF 窗口在右侧和底部有不需要的轮廓

c# - 在运行时从字符串创建数学函数

wpf - 在父项中访问子用户控件的数据上下文

c# - 程序化数据绑定(bind)