Xamarin.Forms устанавливают Button ImageSource как встроенный ресурс для загрузки svg - PullRequest
0 голосов
/ 01 апреля 2020

Я хотел бы поместить svg внедренное изображение как ImageSource для Button в Xamarin.Forms, что-то вроде этого

<Button Text="Button" ImageSource="resource://fullname.svg">
</Button>

, возможно, применяя Transformation к svg (из FFImageLoading.Transformations ), но это плюс.

Я пробовал этот синтаксис

<Button Text="Button"
  ImageSource="{ext:ImageResourceExtension fullname.svg}" />

c#

    public class ImageResourceExtension : IMarkupExtension
    {
        private static Assembly Assembly = typeof(ImageResourceExtension).GetTypeInfo().Assembly;

        public string Source { get; set; }

        public object ProvideValue(IServiceProvider serviceProvider)
        {
            if (Source == null) return null;
            return SvgImageSource.FromResource(Source, Assembly, 32, 32);

        }
   }

Но он не работает.

Более того, я не могу заставить работать этот синтаксис

Source="{resource://fullname.svg, Converter={StaticResource SvgImageSourceConverter}}"

Любая помощь? Спасибо

1 Ответ

1 голос
/ 02 апреля 2020

Как сказал Джейсон, FFImageLoading поддерживает файлы SVG. Выполните следующие действия.

Создайте папку ресурсов в вашей Xamarin.Forms вместо Android части. Затем добавьте файл SVG в качестве встроенного ресурса.

enter image description here

Использование: Используйте SvgCachedImage, чтобы отобразить внедренное изображение SVG и используйте TapGestureRecognizer для имитации события нажатия кнопки.

<ffimageloadingsvg:SvgCachedImage
            HeightRequest="50"
            Source="resource://XamarinDemo.Resources.brightness2.svg"
            WidthRequest="50">
            <ffimageloadingsvg:SvgCachedImage.GestureRecognizers>
                <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"></TapGestureRecognizer>
            </ffimageloadingsvg:SvgCachedImage.GestureRecognizers>
        </ffimageloadingsvg:SvgCachedImage>

Не забудьте добавить пространство имен.

xmlns:ffimageloadingsvg="clr-namespace:FFImageLoading.Svg.Forms;assembly=FFImageLoading.Svg.Forms"

enter image description here

Обновлено: Мы могли бы использовать SkiaSharp, чтобы нарисовать изображение с помощью файла SVG.

MyControl.cs

public class MyControl : Frame
{
    private readonly SKCanvasView _canvasView = new SKCanvasView();
    public MyControl()
    {
        Padding = new Thickness(0);
        BackgroundColor = Color.Transparent;
        Content = _canvasView;

        _canvasView.PaintSurface += CanvasViewOnPaintSurface;
    }
    public static readonly BindableProperty ImageProperty = BindableProperty.Create(
       nameof(Image), typeof(string), typeof(MyControl), default(string), propertyChanged: RedrawCanvas);

    public string Image
    {
        get => (string)GetValue(ImageProperty);
        set => SetValue(ImageProperty, value);
    }
    private static void RedrawCanvas(BindableObject bindable, object oldvalue, object newvalue)
    {
        MyControl svgIcon = bindable as MyControl;
        svgIcon?._canvasView.InvalidateSurface();
    }
    private void CanvasViewOnPaintSurface(object sender, SKPaintSurfaceEventArgs e)
    {
        SKCanvas canvas = e.Surface.Canvas;
        canvas.Clear();


        using (Stream stream = GetType().Assembly.GetManifestResourceStream(Image))
        {
            SkiaSharp.Extended.Svg.SKSvg svg = new SkiaSharp.Extended.Svg.SKSvg();
            svg.Load(stream);

            SKImageInfo info = e.Info;
            canvas.Translate(info.Width / 2f, info.Height / 2f);

            SKRect bounds = svg.ViewBox;
            float xRatio = info.Width / bounds.Width;
            float yRatio = info.Height / bounds.Height;

            float ratio = Math.Min(xRatio, yRatio);

            canvas.Scale(ratio);
            canvas.Translate(-bounds.MidX, -bounds.MidY);

            canvas.DrawPicture(svg.Picture);

        }
    }
}

Использование:

<local:MyControl
            HeightRequest="50"
            Image="XamarinDemo.Resources.brightness2.svg"
            WidthRequest="50" />

И вы можете использовать TapGestureRecognizer для имитации события нажатия кнопки.

...