SyncFusion datagrid crashes "System.ObjectDisposedException: Cannot access a closed Stream" when swiping through the datagrid (containing images) left and right on a mobile screen.

This is the code for assigning the ItemSource to the datagrid. 'FieldVisitItems' is assigned to the ItemSource of the datagrid. I am inserting images in the datagrid and the images are taken from a stream. Is the culprit in the else block where if the image base64 string is empty, I am assigning a null stream. But the datagrid appears in this way as well on the mobile screen, but swiping left right causes it to throw the exception.

            FieldVisitReport obj = new();
        obj.SlNo = FieldVisitItems.Count() + 1;
        obj.AgentName = v.AgentName;
        if (!string.IsNullOrEmpty(v.Image1))
        {
            Stream s = new MemoryStream(Convert.FromBase64String(v.Image1));
            obj.Image1 = ImageSource.FromStream(() => s);
        }
        else
            obj.Image1 = ImageSource.FromStream(() => null);
        if (!string.IsNullOrEmpty(v.Image2))
        {
            Stream s = new MemoryStream(Convert.FromBase64String(v.Image2));
            obj.Image2 = ImageSource.FromStream(() => s);
        }
        else
            obj.Image2 = ImageSource.FromStream(() => null);

        obj.ClientCategory = v.ClientCategory;
        obj.ClientPartyName = v.ClientPartyName;
        obj.ClientPhone = v.ClientPhone;
        obj.TrackingStatus = v.TrackingStatus;
        obj.Datetime = v.DateNTimeUTC.AddHours(5).AddMinutes(30).ToString("dd-MM-yyyy");

        FieldVisitItems.Add(obj);

The Xaml:

            <syncfusion:SfDataGrid.Columns>
            <syncfusion:DataGridTextColumn HeaderText="Sl No" MappingName="SlNo" MinimumWidth="30"/>
            <syncfusion:DataGridImageColumn HeaderText="Product Photo" Aspect="Fill"
                                    MappingName="Image1" MinimumWidth="150">
            </syncfusion:DataGridImageColumn>
            <syncfusion:DataGridImageColumn HeaderText="Competitor Photo" Aspect="Fill"
                                    MappingName="Image2" MinimumWidth="150">
            </syncfusion:DataGridImageColumn>
            <syncfusion:DataGridTextColumn HeaderText="Agent Name" MappingName="AgentName" MinimumWidth="150"/>
            <syncfusion:DataGridTextColumn HeaderText="Client Category" MappingName="ClientCategory" MinimumWidth="150"/>
            <syncfusion:DataGridTextColumn HeaderText="Client Name" MappingName="ClientPartyName" MinimumWidth="150"/>
            <syncfusion:DataGridTextColumn HeaderText="Client Phone" MappingName="ClientPhone" MinimumWidth="150"/>
            <syncfusion:DataGridTextColumn HeaderText="Date" MappingName="Datetime" MinimumWidth="150"/>
            <syncfusion:DataGridTextColumn HeaderText="Tracking Status" MappingName="TrackingStatus" MinimumWidth="150"/>
        </syncfusion:SfDataGrid.Columns>
1

There are 1 best solutions below

4
On BEST ANSWER

In ImageSource.FromStream doc, there is a Remark saying "The delegate provided to stream must return a new stream on every invocation.".

That means the function passed to ImageSource.FromStream must do new MemoryStream every time it is called.

The error message implies that when you swipe, it calls the ImageSource again. I infer that the stream got closed after the first time it was used, so now it needs a new stream.

Try:

var temp = Convert.FromBase64String(v.Image2);

obj.Image2 = ImageSource.FromStream(() =>
    new MemoryStream(temp);

Or:

obj.Image2 = ImageSource.FromStream(() =>
    new MemoryStream(Convert.FromBase64String(v.Image2))
);