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

ImageIconSource can not load svg within IconSourceElement #10081

Open
SongOfYouth opened this issue Oct 18, 2024 · 5 comments
Open

ImageIconSource can not load svg within IconSourceElement #10081

SongOfYouth opened this issue Oct 18, 2024 · 5 comments
Labels
bug Something isn't working needs-triage Issue needs to be triaged by the area owners

Comments

@SongOfYouth
Copy link

SongOfYouth commented Oct 18, 2024

Describe the bug

Can not load svg via ImageIconSource and IconSourceElement like:

<IconSourceElement>
    <ImageIconSource ImageSource="ms-appx:///Assets/Svg/360.svg" />
</IconSourceElement>

or

var element = new IconSourceElement();
var source = new ImageIconSource() { 
    ImageSource = new SvgImageSource(new Uri("ms-appx:///Assets/Svg/360.svg")) 
};
element.IconSource = source;

but the Image and ImageIcon work:

<Image Source="ms-appx:///Assets/Svg/360.svg" />
<ImageIcon Source="ms-appx:///Assets/Svg/360.svg" />

Steps to reproduce the bug

follow above.

Expected behavior

No response

Screenshots

No response

NuGet package version

WinUI 3 - Windows App SDK 1.6.1: 1.6.240923002

Windows version

Windows 11 (22H2): Build 22621

Additional context

No response

@SongOfYouth SongOfYouth added the bug Something isn't working label Oct 18, 2024
@microsoft-github-policy-service microsoft-github-policy-service bot added the needs-triage Issue needs to be triaged by the area owners label Oct 18, 2024
@mareksm
Copy link

mareksm commented Oct 18, 2024

PathIcon can be used to load SVG (C++ version):

auto icon = PathIcon();
winrt::hstring xaml = L"<Path xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"><Path.Data>.....your SVG icon path data.......</Path.Data></Path>";
auto path = winrt::Microsoft::UI::Xaml::Markup::XamlReader::Load(xaml).as<winrt::Microsoft::UI::Xaml::Shapes::Path>();
winrt::Microsoft::UI::Xaml::Media::Geometry geom = path.Data();
path.Data(nullptr);
icon.Data(geom);

@castorix
Copy link

castorix commented Oct 18, 2024

I tested with an InfoBadge and it worked (Windows 10 22H2, Windows App SDK 1.6.240829007) :

            InfoBadge infoBadge = new InfoBadge
            {
                Background = new SolidColorBrush(Colors.DarkBlue)
            };
            ImageIconSource imageIconSource = new ImageIconSource
            {
                ImageSource = new SvgImageSource(new Uri("ms-appx:///Assets/star.svg"))
            };                
            infoBadge.IconSource = imageIconSource;                
            Viewbox viewbox = new Viewbox
            {
                Child = infoBadge,
                Width = 48, 
                Height = 48
            };
            // Add to a StackPanel
            sp1.Children.Add(viewbox);

=>

Image

@SongOfYouth SongOfYouth changed the title ImageIconSource can not load svg ImageIconSource can not load svg within IconSourceElement Oct 18, 2024
@SongOfYouth
Copy link
Author

I tested with an InfoBadge and it worked (Windows 10 22H2, Windows App SDK 1.6.240829007) :

            InfoBadge infoBadge = new InfoBadge
            {
                Background = new SolidColorBrush(Colors.DarkBlue)
            };
            ImageIconSource imageIconSource = new ImageIconSource
            {
                ImageSource = new SvgImageSource(new Uri("ms-appx:///Assets/star.svg"))
            };                
            infoBadge.IconSource = imageIconSource;                
            Viewbox viewbox = new Viewbox
            {
                Child = infoBadge,
                Width = 48, 
                Height = 48
            };
            // Add to a StackPanel
            sp1.Children.Add(viewbox);

=>

Image

Yes, you are right. but i want use it in IconSourceElement, it dosen't work.

@castorix
Copy link

As @mareksm said, you can use Path, like PathIconSource

For example, I copied the path from my star.svg for the test, but you could extract it into a string and bind it :

            <Viewbox MaxWidth="48" MaxHeight="48" Stretch="Uniform">
               <IconSourceElement x:Name="ise1" Margin="2"
                               HorizontalAlignment="Center"
                               VerticalAlignment="Center"
                               Foreground="#FF0"                              >
                   <IconSourceElement.IconSource>
                       <PathIconSource Data="M50,3l12,36h38l-30,22l11,36l-31-21l-31,21l11-36l-30-22h38z" />
                   </IconSourceElement.IconSource>
               </IconSourceElement>
           </Viewbox>

Image

A quick function from ChatGPT to extact the path from .svg file :

    public static string ExtractSvgPathData(string svgFilePath)
    {
        // Load the SVG file as an XDocument
        XDocument svgDocument = XDocument.Load(svgFilePath);

        // Find the first <path> element and get its "d" attribute (path data)
        var pathElement = svgDocument.Descendants().FirstOrDefault(element => element.Name.LocalName == "path");
        if (pathElement != null)
        {
            // Return the value of the "d" attribute
            return pathElement.Attribute("d")?.Value;
        }

        // Return null or empty string if no path data is found
        return null;
    }

@SongOfYouth
Copy link
Author

As @mareksm said, you can use Path, like PathIconSource

For example, I copied the path from my star.svg for the test, but you could extract it into a string and bind it :

            <Viewbox MaxWidth="48" MaxHeight="48" Stretch="Uniform">
               <IconSourceElement x:Name="ise1" Margin="2"
                               HorizontalAlignment="Center"
                               VerticalAlignment="Center"
                               Foreground="#FF0"                              >
                   <IconSourceElement.IconSource>
                       <PathIconSource Data="M50,3l12,36h38l-30,22l11,36l-31-21l-31,21l11-36l-30-22h38z" />
                   </IconSourceElement.IconSource>
               </IconSourceElement>
           </Viewbox>

Image

A quick function from ChatGPT to extact the path from .svg file :

    public static string ExtractSvgPathData(string svgFilePath)
    {
        // Load the SVG file as an XDocument
        XDocument svgDocument = XDocument.Load(svgFilePath);

        // Find the first <path> element and get its "d" attribute (path data)
        var pathElement = svgDocument.Descendants().FirstOrDefault(element => element.Name.LocalName == "path");
        if (pathElement != null)
        {
            // Return the value of the "d" attribute
            return pathElement.Attribute("d")?.Value;
        }

        // Return null or empty string if no path data is found
        return null;
    }

thanks for reply. but for my case, i need to do all in cs code. the data of path can not set via code like this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working needs-triage Issue needs to be triaged by the area owners
Projects
None yet
Development

No branches or pull requests

3 participants