在 mvvm 中显式保存
Posted
技术标签:
【中文标题】在 mvvm 中显式保存【英文标题】:explicit save in mvvm 【发布时间】:2013-04-15 11:37:17 【问题描述】:我有一个包含员工详细信息(全名、年龄、职位)的网格和一个保存按钮。 我希望只有在按下保存按钮时才会保存员工。 如何在 MVVM 中实现它?
<TextBlock
Margin="3"
Text="Full Name:"
VerticalAlignment="Center"
/>
<TextBox
Grid.Column="1"
Margin="3"
Text="Binding FullName, UpdateSourceTrigger=Explicit, ValidatesOnDataErrors=True"
/>
<TextBlock
Grid.Row="1"
Margin="3"
Text="Age:"
VerticalAlignment="Center"
/>
<TextBox
Grid.Column="1"
Grid.Row="1"
Margin="3"
Text="Binding Age, UpdateSourceTrigger=Explicit, ValidatesOnDataErrors=True"
/>
<TextBlock
Grid.Row="2"
Margin="3"
Text="Position:"
VerticalAlignment="Center"
/>
<TextBox
Grid.Column="1"
Grid.Row="2"
Margin="3"
Text="Binding Position, UpdateSourceTrigger=Explicit, ValidatesOnDataErrors=True"
/>
<Button
Grid.Row="4"
Grid.ColumnSpan="2"
Content="Save"
Command="Binding SaveCommand"
Width="80"
Height="22"
Margin="3"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
/>
我的 View 模型没有实现 Save 方法: 我不确定我知道如何处理显式绑定......
public string FullName
get return _emp.FullName;
set
_emp.FullName = value;
OnPropertyChanged("FullName");
public int Age
get return _emp.Age;
set
_emp.Age = value;
OnPropertyChanged("Age");
public string Position
get return _emp.Position;
set
_emp.Position = value;
OnPropertyChanged("Position");
public EmployeeViewModel(Employee emp)
_emp = emp;
_employees = new ObservableCollection<EmployeeViewModel>();
if (_emp.Employees != null)
foreach (Employee employee in _emp.Employees)
_employees.Add(new EmployeeViewModel(employee));
public string[] ValidatedProperties =
"FullName",
"Age",
"Position"
;
public RelayCommand SaveCommand
get
return _saveCommand ??
(_saveCommand = new RelayCommand(Save, CanSave));
set _saveCommand = value;
private bool CanSave()
foreach (string property in ValidatedProperties)
if (!string.IsNullOrEmpty(GetValidationError(property)))
return false;
return true;
private void Save()
throw new NotImplementedException();
【问题讨论】:
关于DataAccess
层,您使用的是什么?使用EntityFramework
模型?或SQL adapter
?或者您是否希望在单击保存命令时以编程方式将员工的 List
或 Collection
添加到网格中?
为什么要使用 UpdateSourceTrigger=Explicit?
简单列表save
是什么意思?你的意思是从前端保存到ViewModel
还是数据库?
到 viewModel 并最终到数据库(在这种情况下只是内存中的一个简单列表)
【参考方案1】:
经过一番挖掘,我发现了一些不错的技术,使用命令参数+转换器。 http://www.shujaat.net/2011/01/updatesourcetrigger-explicit-for-mvvm.html
所以在我的情况下:
<TextBlock
Margin="3"
Text="Full Name:"
VerticalAlignment="Center"
/>
<TextBox
x:Name="FullNameTextBox"
Grid.Column="1"
Margin="3"
Text="Binding FullName, UpdateSourceTrigger=Explicit, ValidatesOnDataErrors=True"
/>
<TextBlock
Grid.Row="1"
Margin="3"
Text="Age:"
VerticalAlignment="Center"
/>
<TextBox
x:Name="AgeTextBox"
Grid.Column="1"
Grid.Row="1"
Margin="3"
Text="Binding Age, UpdateSourceTrigger=Explicit, ValidatesOnDataErrors=True"
/>
<TextBlock
Grid.Row="2"
Margin="3"
Text="Position:"
VerticalAlignment="Center"
/>
<TextBox
x:Name="PositionTextBox"
Grid.Column="1"
Grid.Row="2"
Margin="3"
Text="Binding Position, UpdateSourceTrigger=Explicit, ValidatesOnDataErrors=True"
/>
<Button
Grid.Row="4"
Grid.ColumnSpan="2"
Content="Save"
Command="Binding SaveCommand"
Width="80"
Height="22"
Margin="3"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
>
<Button.CommandParameter>
<MultiBinding Converter="StaticResource EmployeeConverter">
<Binding ElementName="FullNameTextBox" Path="Text" />
<Binding ElementName="AgeTextBox" Path="Text" />
<Binding ElementName="PositionTextBox" Path="Text" />
</MultiBinding>
</Button.CommandParameter>
</Button>
</Grid>
对 viewModel 的更改:
private RelayCommand<object> _saveCommand;
public RelayCommand<object> SaveCommand
get
return _saveCommand ??
(_saveCommand = new RelayCommand<object>(Save, CanSave));
set _saveCommand = value;
private bool CanSave(object value)
foreach (string property in ValidatedProperties)
if (!string.IsNullOrEmpty(GetValidationError(property)))
return false;
return true;
private void Save(object value)
string[] parameters = ((string)value).Split(new char[] ':' );
FullName = parameters[0];
Age = Convert.ToInt32(parameters[1]);
Position = parameters[2];
还有小转换器:
public class EmployeeConverter : IMultiValueConverter
public object Convert(object [] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
string fullName = (string)values[0];
string age = (string)values[1];
string position = (string)values[2];
return string.Format("0:1:2", fullName, age, position);
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
throw new NotImplementedException();
【讨论】:
以上是关于在 mvvm 中显式保存的主要内容,如果未能解决你的问题,请参考以下文章