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

Issues with rendering when using ItemsSource #11

Open
ghost opened this issue Aug 29, 2017 · 0 comments
Open

Issues with rendering when using ItemsSource #11

ghost opened this issue Aug 29, 2017 · 0 comments

Comments

@ghost
Copy link

ghost commented Aug 29, 2017

I've been trying to use ItemsSource property of a ListView to render a bunch of SVG images and had no luck. After debugging it a bit, I think there is an issue with SvgImage class.

Consider this xaml:

<Grid Background="Purple">
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>

    <ListView x:Name="SvgForXamlListView">
        <ListView.ItemTemplate>
            <DataTemplate x:Key="SvgForXamlDataTemplate">
                <svg:SvgImage Margin="10" Width="100" Height="100" Content="{Binding Document}" />
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

    <StackPanel Orientation="Horizontal" Grid.Row="1">
        <Button Content="Draw" Click="OnDrawClick" />
        <Button Content="Navigate" Click="OnNavigateClick" />
    </StackPanel>
</Grid>

And this code-behind:

public sealed partial class MainPage
{
    public MainPage()
    {
        InitializeComponent();
    }

    private async void OnDrawClick(object sender, RoutedEventArgs e)
    {
        var svgFiles = new []
        {
            "ms-appx:///Assets/test1.svg",
            "ms-appx:///Assets/test2.svg",
            "ms-appx:///Assets/test3.svg",
            "ms-appx:///Assets/test4.svg"
        };

        var viewModels = new List<SvgImageViewModel>();
        foreach (var svgFile in svgFiles)
        {
            var viewModel = new SvgImageViewModel();
            await viewModel.InitializeAsync(svgFile);
            viewModels.Add(viewModel);
        }

        SvgForXamlListView.ItemsSource = viewModels;
    }

    private void OnNavigateClick(object sender, RoutedEventArgs e)
    {
        Frame.Navigate(typeof(Page2));
    }
}

public class SvgImageViewModel
{
    public Uri SvgUri { get; private set; }

    public SvgDocument Document { get; private set; }

    public async Task InitializeAsync(string fileUri)
    {
        this.SvgUri = new Uri(fileUri);

        var file = await StorageFile.GetFileFromApplicationUriAsync(SvgUri);

        using (var stream = await file.OpenStreamForReadAsync())
        using (var reader = new StreamReader(stream))
        {
            var xml = new XmlDocument();
            xml.LoadXml(reader.ReadToEnd(), new XmlLoadSettings { ProhibitDtd = false });
            var svgDocument = SvgDocument.Parse(xml);
            this.Document = svgDocument;
        }
    }
}

The above does not render anything on the screen. Even though it does create 4 instances of SvgImage controls and places them in the UI tree, the CanvasControl does not render anything. Debugging through this I see that when using ItemsSource, SvgImage.OnContentChanged is called before SvgImage.OnApplyTemplate. Therefore at the time that content is being applied, _canvasControl instance is NULL and so _renderer is not created.

Making the following change to the constructor of SvgImage resolves this problem because it ensures that the control will render its content after it is loaded, and then also whenever the content changes thereafter. It also takes care of safely unloading the underlying CanvasControl whenever SvgImage is unloaded:

public SvgImage()
    : base()
{
    this.DefaultStyleKey = typeof(SvgImage);
    Loaded += (sender, args) => OnContentChanged(this.Content);
    Unloaded += (sender, args) => SafeUnload();
}

If this sounds like a correct fix to your SVG viewer then I can make a pull request against your repository with my suggested fixes.

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

No branches or pull requests

0 participants