I'm using a MVVM pattern with Prism, and I have run into a problem with Commands.
*I'm not using the CslaDataProvider in my app.
In my ViewModel object, I have a property "Server" that is an editableroot. There is a function ("SaveServerEditsCommand") that takes in a "Server" object and performs the save operation on it. What is odd is that the Save performs correctly, and the IsDirty flag gets set to false. However, when the function completes, the "Server" object's IsDirty flag is set to true. Has anyone seen something like this happen?
<
Button Content="Save" Command="{Binding Path=SaveServerEditsCommand}" CommandParameter="{Binding Path=Server, Mode=TwoWay}">private
void SaveServerEdits(CSLABusinessObjects.Server server){
if (server == null) return;
try
{
server.ApplyEdit();
Server savable = server.Clone();
server = savable.Save();
(server as Csla.Core.ISavable).SaveComplete(server);
server.BeginEdit();
catch
{
}
SaveServerEditsCommand.RaiseCanExecuteChanged();
CancelServerEditsCommand.RaiseCanExecuteChanged();
}
I don't see the specific issue. Here are some comments:
Thank you for the response. I made the modifications you suggested in points 1 and 2. There is no SaveComplete() handler. I put breakpoints on the lines in red. The first breakpoint to hit is the one in CanSaveServerEdits. This is because I raised the SaveServerEditsCommand.RaiseCanExecuteChanged event. The parameter passed into the function is dirty. The next breakpoint to hit is the one last one in SaveServerEdits, telling me that the object is not dirty. This suggests to me that there are actually two objects.
I'm wondering if WPF is creating a clone of the datacontext object before passing it as a command parameter. Any ideas on how to trouble shoot it?
private bool CanSaveServerEdits(CSLABusinessObjects.Server server)
{
if (server == null) return false;
return server.IsSavable;
}
private void SaveServerEdits(CSLABusinessObjects.Server server)
{
if (server == null) return;
try
{
server.ApplyEdit();
server = server.Save();
((Csla.Core.ISavable)server).SaveComplete(server);
server.BeginEdit();
}
catch(Exception ex)
{
}
SaveServerEditsCommand.RaiseCanExecuteChanged();
CancelServerEditsCommand.RaiseCanExecuteChanged();
if (server.IsDirty)
return;
else
return; // Breakpoint stops here.
}
So to be clear, you are saying that IsDirty is false at the
BOTTOM of your method, but that the object WPF binds to has IsDirty as true.
Meaning that WPF isn’t binding to the object you get back from Save().
So my question is this: where does your code update the form’s
DataContext to use the new object?
THERE ARE TWO OBJECTS – the Save() method returns a new
object. If you don’t tell WPF to use that new object, it will just keep
using the old object.
When using a data provider, the DataContext is updated
automatically. But using your approach, it seems to me that your code will need
to update the DataContext somehow.
Rocky
To setup the binding, I have a ServerView object that has a Model property. When the Model property is set, the ServerViewModel is assigned to the DataContext property of the ServerView. The actual assignment occurs when the ServerViewModel is constructed.
I get the idea that calling EditableRoot.Save() will return another object. So I think what I'm hearing is that calling...
server = server.Save();
will cause a disconnect with databinding, and the DataContext will not be updated.
The Save() method returns a new instance of the object. You need
to get your view to bind to that new object.
Rocky
Copyright (c) Marimer LLC