WPF文本框绑定问题

时间:2009-11-25 16:54:11

标签: 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为空。

ViewModel -

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

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

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

2 个答案:

答案 0 :(得分:2)

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

(在您的保存方法中)

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}"/>

希望这会有所帮助:)

答案 1 :(得分:1)

如果我理解你,Clear Command将准备VM接受新的Employee,那么为什么不在Clear方法中初始化一个新的SelectedEmployee并将其添加到Employees集合中呢?

private void Clear() 
 {
      // to clear all the textboxes before adding new employee info.
      SelectedEmployee = new Employee{FirstName="",LastName=""};
      Employees.Add(SelectedEmployee);
      OnPropertyChanged("SelectedEmployee");
  }