How do entity self-tracking with changes in VM and UI?
my context: Entity Framework 4.0 + WCF Ria Data Service + Silverlight 4. Suppose I have entity People from EF, then I created PeopleVM like:
public class PeopleViewModel : ViewModelBase
{
public PeopleViewModel(){
//....
this._hasChanges = MyDomainContext.HasChanges;
}
private People _People;
public People People
{
get { return _People; }
set
{
if (value != this._People)
{
开发者_StackOverflow社区 value = this._People;
this.RaisePropertyChanged("People");
}
}
}
private bool _hasChanges;
public bool HasChanges
{
get { return this._hasChanges; }
set
{
if (this._hasChanges != value)
{
this._hasChanges = value;
this.RaisePropertyChanged("HasChanges");
}
}
}
//........
private RelayCommand _saveCommand = null;
public RelayCommand SaveCommand
{
//.....
}
private RelayCommand _cancelCommand = null;
public RelayCommand CancelCommand
{
//.....
}
}
in UI xaml, I set binding as:
<TextBox Text="{Binding People.FirstName, Mode=TwoWay}" />
<TextBox Text="{Binding People.LasttName, Mode=TwoWay}" />
Then I set button in UI as:
<Button Content="Save" Command="{Binding SaveCommand}" IsEnabled="{Binding HasChanges}"/>
<Button Content="Undo" Command="{Binding CancelCommand}" IsEnabled="{Binding HasChanges}"/>
So what I want is:
initially, button should be disabled because there is no data changes.
when user type some in FirstName, LastName textbox, the button should be enabled.
But with above code, even I change firstname, lastname, the button still in disable status.
How to resolve this problem?
The problem is that your viewmodel's HasChanges property is not updated when your domain context HasChanges property is updated. I typically just expose the Domain Context as a property on the view model and bind the buttons enabled state directly to its HasChanges property.
public class PeopleViewModel : ViewModelBase
{
public PeopleViewModel(DomainContext context){
this.Context = context;
}
public DomainContext Context
{ get; private set; }
private People _People;
public People People
{
get { return _People; }
set
{
if (value != this._People)
{
value = this._People;
this.RaisePropertyChanged("People");
}
}
}
//........
private RelayCommand _saveCommand = null;
public RelayCommand SaveCommand
{
//.....
}
private RelayCommand _cancelCommand = null;
public RelayCommand CancelCommand
{
//.....
}
}
Here is the XAML for the UI to bind to the context's HasChanges:
<Button Content="Save" Command="{Binding SaveCommand}" IsEnabled="{Binding Context.HasChanges}"/>
<Button Content="Undo" Command="{Binding CancelCommand}" IsEnabled="{Binding Context.HasChanges}"/>
You must make sure that the People object is pulled out of the DomainContext in order for updates to affect the HasChanges property of that DomainContext.
精彩评论