This question is locked. New answers and comments are not allowed.
I've been implementing sucessfully the QueryableDataServiceCollectionView using a fully functional MVVM pattern.
I have a gridview, pager and a set of buttons (Save, Reject, Refresh) implementing the ICommand (with the CanExecute) so that they can automatically deactivate/active based on the CollectionView status property HasChanges.
Somehow, this works perfectly until i try to insert a new row using the RadGridView's builtin insert pivot row.
After i insert a record using the above method, the HasChanges property on the QueryableDataServiceCollectionView never gets updated again, even if I update some records.
My goal is to allow to user to produce a set of changes and then use the Submit or Reject changes in the CollectionView.
Facts:
All the CRUD operations are done using the RadGridView's builtin UI operations, there is no code involved for CRUD operations.
This behavior is happening without ever calling SubmitChanges, so there is no server interaction involved in this process.
I can successfully reproduce this behavior by executing the following steps:
1. Edit a row using the RadGridView's builtin edit feature (double click on the cell) and commit the changes to the CollectionView by pressing Enter. Notice that the HasChanges property has changed to True.
2. Undo the operation by calling RejectChanges on the CollectionView. Notice that the HasChanges property has changed to False.
3. Insert a new row using the RadGridView's builtin insert feature (ShowInsertRow="True") and commit the changes to the CollectionView by pressing Enter. Notice that the HasChanges property has changed to True.
4. Undo the operation by calling RejectChanges on the CollectionView. Notice that the HasChanges property has changed to False.
5. After this step, the CollectionView is somehow broken because the HasChanges will never get changed again and will be allways defaulted to False. You can confirm this by making any change on the RadGridView (updating, inserting or deleting).
This is a issue in my case because it breaks the chain of my Save & Undo buttons making them to never get enabled again because the CanExecute event (ICommand) will allways return false, because HasChanges is allways false.
Here is my ViewModel:
I have a gridview, pager and a set of buttons (Save, Reject, Refresh) implementing the ICommand (with the CanExecute) so that they can automatically deactivate/active based on the CollectionView status property HasChanges.
Somehow, this works perfectly until i try to insert a new row using the RadGridView's builtin insert pivot row.
After i insert a record using the above method, the HasChanges property on the QueryableDataServiceCollectionView never gets updated again, even if I update some records.
My goal is to allow to user to produce a set of changes and then use the Submit or Reject changes in the CollectionView.
Facts:
All the CRUD operations are done using the RadGridView's builtin UI operations, there is no code involved for CRUD operations.
This behavior is happening without ever calling SubmitChanges, so there is no server interaction involved in this process.
I can successfully reproduce this behavior by executing the following steps:
1. Edit a row using the RadGridView's builtin edit feature (double click on the cell) and commit the changes to the CollectionView by pressing Enter. Notice that the HasChanges property has changed to True.
2. Undo the operation by calling RejectChanges on the CollectionView. Notice that the HasChanges property has changed to False.
3. Insert a new row using the RadGridView's builtin insert feature (ShowInsertRow="True") and commit the changes to the CollectionView by pressing Enter. Notice that the HasChanges property has changed to True.
4. Undo the operation by calling RejectChanges on the CollectionView. Notice that the HasChanges property has changed to False.
5. After this step, the CollectionView is somehow broken because the HasChanges will never get changed again and will be allways defaulted to False. You can confirm this by making any change on the RadGridView (updating, inserting or deleting).
This is a issue in my case because it breaks the chain of my Save & Undo buttons making them to never get enabled again because the CanExecute event (ICommand) will allways return false, because HasChanges is allways false.
Here is my ViewModel:
public
class
ImdbTitlesViewModel : ViewModelBase
{
private
ImdbDataContext _imdbContext;
private
QueryableDataServiceCollectionView<ImdbTitle> _imdbTitlesView;
public
QueryableDataServiceCollectionView<ImdbTitle> ImdbTitlesView
{
get
{
return
_imdbTitlesView; }
}
public
IEnumerable<ImdbTitle> ImdbTitles
{
get
{
return
this
._imdbTitlesView;
}
}
private
ImdbTitle _selectedTitle;
public
ImdbTitle SelectedTitle
{
get
{
return
this
._selectedTitle; }
set
{
if
(
this
._selectedTitle != value)
{
this
._selectedTitle = value;
RaisePropertyChanged(
"SelectedTitle"
);
}
}
}
private
bool
_isBusy;
public
bool
IsBusy
{
get
{
return
this
._isBusy; }
set
{
if
(
this
._isBusy != value)
{
this
._isBusy = value;
RaisePropertyChanged(
"IsBusy"
);
}
}
}
public
RelayCommand Startup {
get
;
set
; }
public
RelayCommand Refresh {
get
{
return
LoadImdbTitles; }
set
{ LoadImdbTitles = value; } }
public
RelayCommand LoadImdbTitles {
get
;
set
; }
public
RelayCommand SaveChanges {
get
;
set
; }
public
RelayCommand RejectChanges {
get
;
set
; }
/// <summary>
/// Initializes a new instance of the ImdbTitlesViewModel class.
/// </summary>
public
ImdbTitlesViewModel()
{
Startup =
new
RelayCommand(OnStartup);
LoadImdbTitles =
new
RelayCommand(OnLoadImdbTitles, CanLoadImdbTitles);
SaveChanges =
new
RelayCommand(OnSaveChanges, CanSaveChanges);
RejectChanges =
new
RelayCommand(OnRejectChanges, CanRejectChanges);
if
(IsInDesignMode)
{
// Code runs in Blend --> create design time data.
}
else
{
// Code runs "for real": Connect to service, etc...
this
._imdbContext =
new
ImdbDataContext();
this
._imdbTitlesView =
new
QueryableDataServiceCollectionView<ImdbTitle>(
this
._imdbContext,
this
._imdbContext.ImdbTitles);
this
._imdbTitlesView.LoadedData +=
new
EventHandler<Telerik.Windows.Controls.DataServices.LoadedDataEventArgs>(OnImdbTitlesViewLoadedData);
this
._imdbTitlesView.PropertyChanged +=
new
System.ComponentModel.PropertyChangedEventHandler(OnImdbTitlesViewPropertyChanged);
this
._imdbTitlesView.PageSize = 25;
this
._imdbTitlesView.AutoLoad =
true
;
this
._imdbTitlesView.SubmittedChanges +=
new
EventHandler<Telerik.Windows.Controls.DataServices.DataServiceSubmittedChangesEventArgs>(OnImdbTitlesViewSubmittedChanges);
}
}
void
OnImdbTitlesViewSubmittedChanges(
object
sender, Telerik.Windows.Controls.DataServices.DataServiceSubmittedChangesEventArgs e)
{
if
(e.HasError)
{
e.MarkErrorAsHandled();
MessageBox.Show(e.Error.Message,
"Error occurred"
, MessageBoxButton.OK);
}
else
{
MessageBox.Show(
"Changes saved successfully!"
,
"Notification"
, MessageBoxButton.OK);
}
}
void
OnImdbTitlesViewPropertyChanged(
object
sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if
(e.PropertyName.Equals(
"IsBusy"
))
{
this
.IsBusy =
this
._imdbTitlesView.IsBusy;
}
if
(e.PropertyName.Equals(
"HasChanges"
))
{
SaveChanges.RaiseCanExecuteChanged();
RejectChanges.RaiseCanExecuteChanged();
}
}
void
OnImdbTitlesViewLoadedData(
object
sender, Telerik.Windows.Controls.DataServices.LoadedDataEventArgs e)
{
if
(e.HasError)
{
e.MarkErrorAsHandled();
MessageBox.Show(e.Error.Message,
"Error occurred"
, MessageBoxButton.OK);
}
}
private
void
OnStartup()
{
// We dont need to startup because the DataView has the property AutoLoad = true
//GetImdbTitles();
}
private
bool
CanLoadImdbTitles()
{
return
!IsBusy;
}
private
void
OnLoadImdbTitles()
{
// Execute the query.
//this.RejectChanges.Execute(null);
this
._imdbTitlesView.Load(
true
);
//this._imdbTitlesView.Load(true);
}
private
bool
CanSaveChanges()
{
if
(
this
.IsBusy)
return
false
;
if
(
this
._imdbTitlesView.HasChanges)
return
true
;
return
false
;
}
private
void
OnSaveChanges()
{
this
._imdbTitlesView.SubmitChanges();
}
private
void
OnRejectChanges()
{
this
._imdbTitlesView.RejectChanges();
}
private
bool
CanRejectChanges()
{
if
(
this
.IsBusy)
return
false
;
if
(
this
._imdbTitlesView.HasChanges)
return
true
;
else
return
false
;
}
public
override
void
Cleanup()
{
// Clean own resources if needed
base
.Cleanup();
}
}