我有一个 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/