我有一个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来解决.....但还有其他出路吗?
答案 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");
}