Xamarin.Forms.Plugins icon indicating copy to clipboard operation
Xamarin.Forms.Plugins copied to clipboard

SVG element "Clicked" attiribute support

Open georgeedwards opened this issue 9 years ago • 9 comments

It would be great if SVG elements could be used as buttons and supported the Clicked atribute to trigger click actins.

georgeedwards avatar Jan 16 '16 10:01 georgeedwards

You can use SVG elements as "Buttons". At least you can add a tap listener for example.

<abstractions:SvgImage Grid.Row="1" Grid.Column="1" SvgAssembly="{Binding SvgAssembly}" SvgPath="Core.Images.PreviousButton.svg" HeightRequest="150" WidthRequest="150" > <abstractions:SvgImage.GestureRecognizers> <TapGestureRecognizer Command="{Binding PlayPreviousSongCommand}"></TapGestureRecognizer> </abstractions:SvgImage.GestureRecognizers> </abstractions:SvgImage>

ghost avatar Feb 29 '16 00:02 ghost

Semantically SVG is image, so I believe SvgImage class should provide image related interface only. I usually create a custom ImageButton class in my project which contains several subviews: 1. transparent button for hitzone 2. image itself 3. tap animation effect. BTW for usability it's generally better to have hitzone a bit larger than visible element size, so when hitzone is defined as separate subview, you have more flexibility and cleaner architecture. Just IMO.

rudyryk avatar Mar 15 '16 20:03 rudyryk

@nicky112 Here is some example code from my project that allows you to click an SVGImage.

//Put this in your Shared Project
public class SVGImageButton : ContentView
{
    private readonly TapGestureRecognizer tgr;
    public EventHandler Clicked;

    private readonly SvgImage image;

    public string ImageName
    {
        set
        {
            image.SvgPath = SVGViewModel.GetPath(value);
        }
    }

    public SVGImageButton()
    {
        HorizontalOptions = LayoutOptions.FillAndExpand;
        VerticalOptions = LayoutOptions.FillAndExpand;

        image = new SvgImage {
            SvgAssembly = SVGViewModel.assembly, 
            HeightRequest = 44.0,
            WidthRequest = 44.0,
            HorizontalOptions = LayoutOptions.CenterAndExpand,
            VerticalOptions = LayoutOptions.CenterAndExpand
        };

        tgr = new TapGestureRecognizer();
        tgr.Tapped += (object sender, EventArgs e) => {
            if(Clicked != null)
            {
                Clicked(sender, e);
            }
        };

        GestureRecognizers.Add(tgr);
        Content = image;
    }
}

//Put this in your PCL Project
public static class SVGViewModel
{
    public static readonly Assembly assembly = this.GetType().GetTypeInfo().Assembly;

    public static string GetPath(string svgName)
    {
        string path = string.Format("PCLProject.Images.{0}.svg", svgName);
        return path;
    }
}

zippo227 avatar Jun 01 '16 13:06 zippo227

@zippo227 I tried your code but i get an unhandled exception if i set Content = image during the rendering phase.

VisionFlare avatar Apr 26 '17 09:04 VisionFlare

I haven't seen that issue. Perhaps you could try the code below to ensure it does not happen during render. @VisionFlare

Device.BeginInvokeOnMainThread(()=>{ Content= image; });

zippo227 avatar Apr 26 '17 13:04 zippo227

@zippo227 I can't use this line of code: public static readonly Assembly assembly = typeof(this).GetTypeInfo().Assembly;

Is this the proper way of writing it or did you maybe do a typo?

RaZp29 avatar Jul 11 '17 14:07 RaZp29

I don't think I had a typo, but it looks like you are right and typeof(this) does not work. Try this instead:

public static readonly Assembly assembly = this.GetType().GetTypeInfo().Assembly;

I have modified my code above to "Reflect" (hehe) this change.

zippo227 avatar Jul 11 '17 16:07 zippo227

still won't work @zippo227 skarmavbild 2017-07-12 kl 08 15 25 skarmavbild 2017-07-12 kl 08 15 48 skarmavbild 2017-07-12 kl 08 16 10

RaZp29 avatar Jul 12 '17 06:07 RaZp29

@RaZp29 could it be because your class is static?

zippo227 avatar Jul 13 '17 17:07 zippo227