【问题标题】:WPF textbox binding issueWPF 文本框绑定问题
【发布时间】:2010-12-20 09:05:06
【问题描述】:

我有一个 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 将简单地清除文本框,而 save 将添加或编辑记录。我在 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");
      }
 }

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

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

【问题讨论】:

  • 我在您的帖子中没有看到任何问号。你在问什么?

标签: wpf mvvm binding textbox


【解决方案1】:

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

(在您的 Save 方法中)

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

如果您希望文本框在用户更改数据网格中的选定项目时刷新,您需要覆盖 SelectedEmployee 上的设置器,例如:

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

希望这会有所帮助:)

【讨论】:

  • 感谢大家的回复。
【解决方案2】:

如果我理解你的话,Clear 命令将使 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");
  }

【讨论】:

    猜你喜欢
    • 2023-04-06
    • 2010-11-11
    • 1970-01-01
    • 2012-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-24
    相关资源
    最近更新 更多