This is a migrated thread and some comments may be shown as answers.

Row Item is not being updated...

3 Answers 71 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Joshua
Top achievements
Rank 1
Joshua asked on 25 May 2011, 02:20 AM
I built the original Silverlight app using WCF RIA services and worked fine.

However, I'm needing to use the app in SharePoint as a web part and, unfortunately, SP2010 doesn't use EF4.  Therefore, I had to exposed my database through the standard WCF Data Services (oData).  All information is read and displayed correctly.  However, values aren't written back to my database.  What am I doing wrong?

WCF Service:
namespace Checks_Console.Web
{
    public class WCFChecksConsole : DataService<EntitiesContainer>
    {
        public static void InitializeService(DataServiceConfiguration config)
        {
            config.SetEntitySetAccessRule("*", EntitySetRights.All);
            config.MaxExpandDepth = int.MaxValue;
            config.MaxExpandCount = int.MaxValue;
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
        }
    }
}

MainPage.xaml
<telerik:RadGridView Name="rgvCheckRequests" Visibility="Collapsed"
                             Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"
                             ShowGroupPanel="False" 
                             RowIndicatorVisibility="Visible" Margin="10"
                             CanUserDeleteRows="False"
                             ShowInsertRow="False"
                             CanUserReorderColumns="False"
                             CanUserResizeColumns="True"
                             AutoGenerateColumns="False"
                             CanUserFreezeColumns="False"
                             VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
                             RowEditEnded="rgvCheckRequests_RowEditEnded" DataLoaded="rgvCheckRequests_DataLoaded">
            <telerik:RadGridView.FilterDescriptors>
                <telerikData:CompositeFilterDescriptor LogicalOperator="Or">
                    <telerikData:CompositeFilterDescriptor.FilterDescriptors>
                        <telerikData:FilterDescriptor Member="CheckRequestStatus.Name" Operator="IsEqualTo" Value="Requested" IsCaseSensitive="False" />
                        <telerikData:FilterDescriptor Member="CheckRequestStatus.Name" Operator="IsEqualTo" Value="OnHold" IsCaseSensitive="False" />
                        <telerikData:FilterDescriptor Member="CheckRequestStatus.Name" Operator="IsEqualTo" Value="Rejected" IsCaseSensitive="False" />
                    </telerikData:CompositeFilterDescriptor.FilterDescriptors>
                </telerikData:CompositeFilterDescriptor>
            </telerik:RadGridView.FilterDescriptors>
            <telerik:RadGridView.Columns>
                <telerik:GridViewComboBoxColumn DataMemberBinding="{Binding Path=CheckRequestStatusEnumId}" SelectedValueMemberPath="EnumId" DisplayMemberPath="Name" Header="Status" Width="75" UniqueName="Status" IsFilterable="True" />
                <telerik:GridViewDataColumn DataMemberBinding="{Binding Path=Consumer.Contact.FirstName}" Header="First Name" Width="120" UniqueName="FirstName" IsFilterable="False" />
                <telerik:GridViewDataColumn DataMemberBinding="{Binding Path=Consumer.Contact.LastName}" Header="Last Name" Width="120" UniqueName="LastName" IsFilterable="False" />
                <telerik:GridViewDataColumn DataMemberBinding="{Binding Path=Address.Line1}" Header="Address 1" Width="165" UniqueName="Address1" IsFilterable="False" />
                <telerik:GridViewDataColumn DataMemberBinding="{Binding Path=Address.Line2}" Header="Address 2" Width="165" UniqueName="Address2" IsFilterable="False" />
                <telerik:GridViewDataColumn DataMemberBinding="{Binding Path=Address.City}" Header="City" Width="125" UniqueName="City" IsFilterable="False" />
                <telerik:GridViewComboBoxColumn DataMemberBinding="{Binding Path=Address.StateId}" SelectedValueMemberPath="Id" DisplayMemberPath="Abbreviation" Header="State" Width="50" UniqueName="State" IsFilterable="False" />
                <telerik:GridViewDataColumn DataMemberBinding="{Binding Path=Address.Zip}" Header="Zip" Width="65" UniqueName="Zip" IsFilterable="False" />
                <telerik:GridViewDataColumn DataMemberBinding="{Binding Path=VeterinaryClinic.Name}" Header="Veterinary Clinic" Width="220" UniqueName="ClinicName" IsFilterable="False" />
                <telerik:GridViewDataColumn DataMemberBinding="{Binding Path=Pet.Name}" Header="Pet Name" Width="100" UniqueName="PetName" IsFilterable="False" />
            </telerik:RadGridView.Columns>
        </telerik:RadGridView>


MainPage.xaml.cs
void MainPage_Loaded(object sender, RoutedEventArgs e)
 {
     svc = new ChecksConsoleService.EntitiesContainer(new Uri(svcURI));
}

(below is called in an onload procedure - again, the records are loaded fine)
DataServiceCollection<ChecksConsoleService.CheckRequest> dscCheckRequests = new DataServiceCollection<ChecksConsoleService.CheckRequest>();
dscCheckRequests.LoadCompleted +=
    (o, args) =>
    {
        rgvCheckRequests.ItemsSource = dscCheckRequests;
    };
var chkreqs = from cr in svc.CheckRequests
                            .Expand("Consumer")
                            .Expand("Consumer/Contact")
                            .Expand("Address")
                            .Expand("Address/State")
                            .Expand("Pet")
                            .Expand("VeterinaryClinic")
                            .Expand("CheckRequestStatus")
              select cr;
  
dscCheckRequests.LoadAsync(chkreqs);

I also tried the event below to no avail (which I believe shouldn't need to be called because of the databinding, but maybe I'm do something wrong here):
private void rgvCheckRequests_RowEditEnded(object sender, GridViewRowEditEndedEventArgs e)
{
    if (e.EditAction == GridViewEditAction.Cancel)
    {
        return;
    }
    if (e.EditOperationType == GridViewEditOperationType.Edit)
    {
        svc.UpdateObject(e.NewData);
    }
}


Thanks,
Joshua

3 Answers, 1 is accepted

Sort by
0
Rossen Hristov
Telerik team
answered on 25 May 2011, 10:28 AM
Hello Joshua,

I am not an expert, but are you calling DataServiceContext.SaveChanges at all?

Anyway, since your problem is not really related to RadGridView, my suggestion is to post your question on the WCF Data Services forum.

Saving changes on the server with a WCF Data Services is beyond the scope of Telerik support. 

Thank you for your understanding.

Regards,
Ross
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Joshua
Top achievements
Rank 1
answered on 25 May 2011, 12:34 PM
Hey Ross,

Thanks for your help.  Unfortunately, there is no SaveChanges() on the context in VS 2010 and Silverlight 4.  Most of the examples I found are from .NET 3.5 in 2009 and Silverlight 2/3 or WPF. 

However, I did get it working after I made this forum post last night.  I just wanted to see if you all had a better approach.  In case anyone else has this issue I, pasted the additional code below.

It appears that UpdateObject only updates the object in the current context, but doesn't persist the changes to the database until BeginSaveChanges is called (the new async method instead of SaveChanges()).  BeginSaveChanges now provides a batch save option to reduce communication between the client and the server.  This approach allows me to, instead of sending updated info to the server on every row edited,:
 
1) Call UpdateObject on RowEditEnded for every object edited
2) Then, have a button on my grid/page that I could attach an event or command to in order to save all changes in one, single async postback, instead of posting back after every edited item.
3) If server/client communication is lagging, this could definitely increase the performance on the client-side app

In my app, the enduser won't be editing a lot of data (the app is more of a reporting tool), so calling BeginSaveChange on every edited item is sufficient.

BeginSaveChanges also has other options instead of just the batch save.

private void rgvCheckRequests_RowEditEnded(object sender, GridViewRowEditEndedEventArgs e)
{
    if (e.EditAction == GridViewEditAction.Cancel)
    {
        return;
    }
    if (e.EditOperationType == GridViewEditOperationType.Edit)
    {
        svc.UpdateObject(e.NewData);
        svc.BeginSaveChanges(SaveChangesOptions.Batch, OnChangesSaved, svc);
    }
}
private void OnChangesSaved(IAsyncResult result)
{
    Dispatcher.BeginInvoke(() =>
        {
            svc = result.AsyncState as ChecksConsoleService.EntityContainer;
            try
            {
                svc.EndSaveChanges(result);
            }
            catch (Exception exc)
            {
                MessageBox.Show("Failed to save record.", "Failed.", MessageBoxButton.OK);
            }
        }
    );
}

Check out the MSDN article for additional info.

Again, thanks for you help.

Joshua
0
Rossen Hristov
Telerik team
answered on 25 May 2011, 12:55 PM
Hello Joshua,

I was not aware that the version you were using did not have the SaveChanges method. Anyway, my idea was that you have to tell the server to actually save the changes be it with the asynchronous BeginSaveChanges or with the other method.

Thanks for sharing your code with the community. I am sure that it will help others as well.

All the best,
Ross
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
Tags
GridView
Asked by
Joshua
Top achievements
Rank 1
Answers by
Rossen Hristov
Telerik team
Joshua
Top achievements
Rank 1
Share this question
or