Example #1
0
        private void ResetImage()
        {
            if (!HasImage)
            {
                return;
            }

            _surface.Background = null;

            if (_brush != null)
            {
                _brush.ImageSource = null;
                _brush             = null;
            }

            if (_source != null)
            {
                _source.ClearResources();
                _source = null;
            }

            HasImage = false;
        }
Example #2
0
        private async void ShowImage()
        {
            if (!CanLoad || !HasAppliedTemplate || !IsLoaded || HasImage)
            {
                return;
            }

            ResetImage();
            if (UriSource == null)
            {
                return;
            }

            SetProgress(0);
            VisualStateManager.GoToState(this, "Unloaded", true);

            // For thread safety, save current value of UriSource
            var uriSource = UriSource;

            HasImage = true;
            using (var stream = await GetImageStreamAsync(uriSource)) // This is not thread-safe!
            {
                // Technically, at each await exists the possibility that UriSource can be changed.
                // We need to ensure that this hasn't happened, otherwise we run the risk of leaking resources
                // or doing other bad things.
                if (uriSource != UriSource)
                {
                    return;
                }

                if (stream == null)
                {
                    VisualStateManager.GoToState(this, "Failed", true);
                    return;
                }

                try
                {
                    var decoder = await BitmapDecoder.CreateAsync(stream);

                    var source = new GifImageSource((int)decoder.PixelWidth, (int)decoder.PixelHeight)
                    {
                        EnablePrerender = true
                    };
                    await source.SetSourceAsync(stream);

                    // It's possible that the URI changed, or the control has been unloaded, etc. If so,
                    // clear resources and quit.
                    if (uriSource != UriSource || !IsLoaded || !CanLoad)
                    {
                        // Clean up GifImageSource and return
                        source.ClearResources();
                        return;
                    }

                    // Must wait for async operations to complete before setting _source
                    _source = source;
                }
                catch (Exception)
                {
                    VisualStateManager.GoToState(this, "Failed", true);
                    return;
                }
            }

            _brush = new ImageBrush {
                ImageSource = _source, Stretch = Stretch.None
            };
            _surface.Background = _brush;

            _surface.Height = _source.Height;
            _surface.Width  = _source.Width;

            // Render one frame so that we show something even if the gif is paused
            _source.RenderFrame();

            VisualStateManager.GoToState(this, "Loaded", true);

            CheckTimer();

            _fireImageOpened = true;
        }