Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Position on stream needs reset in SvgViewbox #155

Closed
ftballguy45 opened this issue Nov 2, 2020 · 9 comments
Closed

Position on stream needs reset in SvgViewbox #155

ftballguy45 opened this issue Nov 2, 2020 · 9 comments

Comments

@ftballguy45
Copy link

When using the SteamSource property of the SvgViewbox, the stream needs to be set to Position = 0 in the OnStreamSourceChanged method, before trying to use the stream. I get exceptions without this, but it works when i added the Position = 0.

@ftballguy45 ftballguy45 changed the title Position on stream needs reset in SvgViewBox Position on stream needs reset in SvgViewbox Nov 2, 2020
@paulushub
Copy link
Contributor

paulushub commented Nov 3, 2020

@ftballguy45 More information needed. How do you get the stream? What is the position on stream before setting the StreamSource property? Currently, the stream is simply copied and position set to start.

MemoryStream svgStream = new MemoryStream();
// On dispose, the stream is close so copy it to the memory stream.
value.CopyTo(svgStream);

// Move the position to the start of the stream
svgStream.Seek(0, SeekOrigin.Begin);

I have not verified what happens if a different property is changed after rendering - it is possible the position will be at the end after the first rendering!
SvgViewbox and SvgCanvas do not reset the original stream, because it is possible the current position is what the user wants.

@ftballguy45
Copy link
Author

ftballguy45 commented Nov 3, 2020

First of all. Thank you so much for this awesome library. What a hole to fill in the .Net stack!

I agree you're right it could be that is what they want, but in my experience I kept getting an error that the root element was missing in the document and it was because the stream being read was at the end. Our situation is probably a bit different than others but doesn't seem that unique. We are loading SVG icons from a database, so the stream is a MemoryStream. The SvgViewbox is databound on the StreamSource property to a property on a viewmodel that is a MemoryStream. I am setting the stream to position 0 in the viewmodel but at some point after the stream has been read, if I have multiple controls bound to the same viewmodel, same property, then one of them will get the stream with the position at the end. As a visual, imagine a UI where we have a listbox of viewmodels in one part of the screen (the listbox items datatemplate contain an SvgViewbox that is bound to the stream in order to show a visual icon). In another part of the screen another SvgViewbox, which is bound to the same viewmodel property also shows a visual icon of the viewmodel. One of the the viewboxes is going to get the stream with the position at the end if they're both bound to the same stream. This is a list of map icons, and then a map that shows the icons on the map in a their lat/long position.

@paulushub
Copy link
Contributor

@ftballguy45 Thanks for the updates and the compliments - I really appreciate it.
It seems the best way is to update the protected virtual DrawingGroup CreateDrawing(Stream svgStream, WpfDrawingSettings settings) method. Please change it to the following and see if this resolves your issue:

        protected virtual DrawingGroup CreateDrawing(Stream svgStream, WpfDrawingSettings settings)
        {
            try
            {
                if (svgStream == null)
                {
                    return null;
                }
                if (svgStream.CanSeek && svgStream.Position != 0)
                {
                    // Move the position to the start of the stream
                    svgStream.Seek(0, SeekOrigin.Begin);
                }

                DrawingGroup drawing = null;

                using (FileSvgReader reader = new FileSvgReader(settings))
                {
                    drawing = reader.Read(svgStream);
                }

                return drawing;
            }
            catch (Exception ex)
            {
                this.OnHandleError(null, ex);
                return null;
            }
        }

If verified I will update the sources accordingly, thanks for the cooperation.

@ftballguy45
Copy link
Author

@paulushub - yes it did work, thank you. Can we get the change in and get a new Nuget package?

@paulushub
Copy link
Contributor

@ftballguy45 By Monday, I will try to get the Nuget package out. Thank you.

paulushub added a commit that referenced this issue Nov 7, 2020
- Fixed the issue #155
- Work around the issue #157
@ftballguy45
Copy link
Author

Hello, just following up on this to see if we can get a new Nuget package published with this fix included

@paulushub
Copy link
Contributor

@ftballguy45 .NET 5 is out, so trying to see if I could add this support too. It should be out soon, sorry.

@paulushub
Copy link
Contributor

@ftballguy45 Sorry for the delay, the nuget package is active.

@ftballguy45
Copy link
Author

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants