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

Change svg fill and brush colour via binding #189

Closed
stojy opened this issue May 25, 2021 · 7 comments
Closed

Change svg fill and brush colour via binding #189

stojy opened this issue May 25, 2021 · 7 comments

Comments

@stojy
Copy link

stojy commented May 25, 2021

A useful feature would be to allow the color defined in the svg to be overridden from a xaml binding (or indeed code behind).

Some use cases that come to mind..

  • Support 'hover over' color changing effect, e.g. allow a binding to be created to change the color when during a mouse over event.
  • Support theming, e.g. allow a dark theme to override the default svg color
  • Support 'off the shelf' svg libraries, e.g. allow a quick way to change a monotone svg (typically black) to something more useful without having to edit the svg.

AFAIK, it's been discussed elsewhere, e.g. #163, #88.

The following code snippet (heavily based on #88 (comment)) integrated into SvgViewbox would provide the functionality to override the 'fill' and 'stroke' brushes. It would need a bit of improvement though to remove the default color brushes mind you.

    public class SvgViewboxEx : SvgViewbox
    {
        public static readonly DependencyProperty FillProperty = DependencyProperty.Register("Fill", typeof(Brush), typeof(SvgViewboxEx), new PropertyMetadata(Brushes.BlueViolet));

        public static readonly DependencyProperty StrokeProperty = DependencyProperty.Register("Stroke", typeof(Brush), typeof(SvgViewboxEx), new PropertyMetadata(Brushes.DarkViolet));

        public Brush Fill
        {
            get => (Brush) GetValue(FillProperty);
            set => SetValue(FillProperty, value);
        }

        public Brush Stroke
        {
            get => (Brush) GetValue(StrokeProperty);
            set => SetValue(StrokeProperty, value);
        }

        protected override void OnSettingsChanged()
        {
            base.OnSettingsChanged();

            var drawings = ((SvgDrawingCanvas) Child).DrawObjects;

            foreach (var drawing in drawings)
            {
                if (drawing is GeometryDrawing geometryDrawing)
                {
                    // svg fill color - translated to a geometry.Brush
                    var brush = new Binding(nameof(Fill))
                                    {
                                        Source = this,
                                        Mode = BindingMode.OneWay
                                    };
                    BindingOperations.SetBinding(geometryDrawing, GeometryDrawing.BrushProperty, brush);

                    // svg stroke color - translated to a geometry.Pen.Brush
                    if (geometryDrawing.Pen != null)
                    {
                        var stroke = new Binding(nameof(Stroke))
                                         {
                                             Source = this,
                                             Mode = BindingMode.OneWay
                                         };
                        BindingOperations.SetBinding(geometryDrawing.Pen, Pen.BrushProperty, stroke);
                    }
                }
            }
        }
    }

At any rate, the above code can be used verbatim for anyone wanting this feature without waiting for an equivalent in SharpVectors.

@paulushub paulushub self-assigned this May 25, 2021
paulushub added a commit that referenced this issue Jul 19, 2022
- SvgBitmap is added as a base class
- SvgIcon is an extension of the SvgBitmap for monochrome SVG files
- Resolves the issue #189
@paulushub
Copy link
Contributor

@stojy Sorry for the delay. SvgIcon is now added to support this feature. It is derived from the WPF Image control. For users requiring more than monochrome features SvgIcon, the base class SvgBitmap is provided and can be extended.

NOTE: I cannot find any case to bind to the pen/stroke, even thought it is supported in SvgIcon. If you have any real world example, please post a sample.

@r-tmp
Copy link

r-tmp commented Sep 4, 2022

@paulushub, don't mean to rush, but do we know when the nuget package that includes this feature will be released?

@paulushub
Copy link
Contributor

@r-tmp Thanks for the interest. Unfortunately, there is still no feedback on this feature. If you find it useful, please test it and provide some feedbacks, that will make it easy to release.

@r-tmp
Copy link

r-tmp commented Sep 6, 2022

@paulushub Just tested it in a small project (.NET 6), not much to say except that seems to be working as expected 🙂.

@spreedated
Copy link

Thanks a lot, I spent like an hour searching for a solution to change the color of my complete black SVG.

You need a reallife example? - Most SVGs are icons used in WPF views. Almost all icons are solid color, most black, unless multicolor icons, but that's a different story.

However, this code works like a charm, and I hope for a integration in the next version.

And maybe someday, multicolor svg icon support, that means, every closed element of a SVG curve can be filled with a different color. e.g. Array of elements with the option to fill each one independently.

@paulushub
Copy link
Contributor

Thanks for the feedback.

And maybe someday, multicolor svg icon support, that means, every closed element of a SVG curve can be filled with a
different color. e.g. Array of elements with the option to fill each one independently.

Will need more information on this, please write more on this if you have the time.

@paulushub
Copy link
Contributor

Sorry for the delay, release 1.8.1 is now available.

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

No branches or pull requests

4 participants