Question

Using Silverlight 5, RIA services 1.0 and Telerik controls I have a dialog with a button that when clicked goes and runs some service code. The issue is when I double click or triple click it real fast, it keeps calling the service thus getting this error:

System.InvalidOperationException: 
System.InvalidOperationException: A SubmitChanges operation is already in progress on this DomainContext.

I was wondering if this is a common error and any work around for it?

Here is the .NET source code that it goes to that causes it to crash:

 public virtual SubmitOperation SubmitChanges(Action<SubmitOperation> callback, object userState)
    {
      if (this.IsSubmitting)
        throw new InvalidOperationException(Resource.DomainContext_SubmitAlreadyInProgress);
Was it helpful?

Solution

This is not an error. A submitChange operation is asynchronous so you have to detect that it is completed before doing something else.

One solution could be to block the user from clicking on the button before the operation is completed.

Since you are using a Telerik controls, you can use a busy indicator.

private void btnUserAction_Click(object sender, RoutedEventArgs e)
{
    myBusyIndicator.IsBusy = true;

    // DO your stuff

    var submitOperation = myContext.SubmitChanges();

    submitOperation.Completed += (s, e) =>
        {
          // It is completed, now the user can click on the button again 

          myBusyIndicator.IsBusy = false;
         }
}

EDIT : The busy indicator should be defined in your Xaml, like this :

<Telerik:RadBusyIndicator x:Name="myBusyIndicator">
            <Grid x:Name="LayoutRoot" >
                 <Button Name="btnUserAction" Click="btnUserAction_Click" />
            </Grid>
</Telerik:RadBusyIndicator>

OTHER TIPS

I had this same problem. So I created a property on my ViewModel and bound it to my IsEnabled property of my button. I set this to false when the save starts and to true when it is done.

<Button Content="Save" IsEnabled="{Binding FinishedDataTransfer}" ...

bool _finishedDataTransfer = false;
public bool FinishedDataTransfer
{
    get { return _finishedDataTransfer; }
    set
    {
        _finishedDataTransfer = value;
        RaisePropertyChanged("FinishedDataTransfer");
    }
}

The advantage of doing it this way instead of a busy indicator is that the user can still do thing with the page while the save is running.

We had same problem, and had to change from sending a command to the viewmodel to having a bit of code behind for button click ...

/// <summary>
/// Workaround for handling double-click from the Map Results button - trying to prevent running the query twice and adding duplicate layers into the Layer Control
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MapResultsButton_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    if (e.ClickCount == 1)
        this.ViewModel.MapResultsCommand.Execute(null);
} 

As you can see, this uses a ClickCount property which is part of the MouseButtonEventArgs

Once the command has reached the viewmodel we can then worry about busy indicators and other ways of disabling the button.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top