Closed djonasdev closed 3 years ago
SvgDrawingCanvas is based on an initial work for a customer, before the library was made public. That is why most parts are commented out. The Runtime classes and the controls like SvgViewbox needs a lot more improvements to be more useful and I have these on my TODO, just trying to improve the conversion process first for now.
Now, what is the actual requirements of your project? Do you need the SvgDrawingCanvas? SvgDrawingCanvas is only useful if you separate the processes; conversion and viewing. The initial requirement for a car wiring manual, converts all the SVG files to XAML files and combine with documentations/instructions in FlowDocument XAML to create an interactive WPF-based manual. So the SvgDrawingCanvas was for the viewing application at the end-users, the conversion library was not shipped to the end-users; only the Runtime library. For most other projects, the controls might be more useful so if you do not mind can you state the actual requirements?
I think it's great that you bring the library back to life and continue to develop! 😀👍
In my project I have a plant visualization! From SolidWorks I can export individual modules as SVG. This makes it possible to implement the layout 1: 1 in my C # application without much effort.
Since it is also possible to select individual stations, I have to color my modules. Therefore, I need access to the individual elements of the SVG.
In detail I have a Grid
and two SvgViewbox
. The background svg is the part of the module which I color.
<Grid>
<svgc:SvgViewbox x:Name="backgroundSvg" Source="4H040339_bg.svg"/>
<svgc:SvgViewbox x:Name="svg" Source="4H040339.svg"/>
</Grid>
As an additional improovement would be to get acces to a named layer inside of the svg. So I could have 2 layer inside of my svg and only color the "background_layer". This could save me a SvgViewbox
.
EDIT
You wrote: SvgDrawingCanvas is only useful if you separate the processes
It would be amazing if it is possible to let the Threadpool
make a conversion between svg
and xaml
. So the gui would be much more responsive! Actually I have a virtualization with more than 60 Objects. If I need to use two SvgViewbox
, I have 120 conversion which run on the gui thread. 🤔
Thanks for the compliments, happy to know this library is useful to your works.
Therefore, I need access to the individual elements of the SVG.
Will modify the controls to allow access to the loaded SVG document, will drop the use of converter classes in the controls. I have being looking for a simple way to let developers use the Element visitor to make modifications in the SVG document at runtime, maybe through a dependency injection.
So I could have 2 layer inside of my svg and only color the "background_layer".
You can loop through the drawings in the DrawingGroup to find the background_layer. Layers are converted to DrawingGroup in the drawings.
It would be amazing if it is possible to let the
Threadpool
make a conversion betweensvg
andxaml
.
The library does not impose any application framework, the SvgDrawingCanvas does not handle conversions, these are handled by the SvgConverter derived classes. The converter classes can be ran in a different thread and even in different .NET domain.
The controls such as SvgViewbox and SvgCanvas do handle conversions, so we could support background conversion here including support for async/await procedures in .NET45 versions.
Just for information, do you have animations in the SVG files?
Will modify the controls to allow access to the loaded SVG document, will drop the use of converter classes in the controls. I have being looking for a simple way to let developers use the Element visitor to make modifications in the SVG document at runtime, maybe through a dependency injection.
I do not understand exactly what you want to tell me
You can loop through the drawings in the DrawingGroup to find the background_layer. Layers are converted to DrawingGroup in the drawings. Ah ok! I have found another way to solve my problem with only 1 svg and without any layers. The
GeometryDrawing.Brush
property is the background of thepath
in the svg. So in default I have a transparant background and the contour is black. So if I modify theGeometryDrawing.Brush
property, the background gets changed.
I wonder just if it is also possible to specify the contour, since currently only the background (of the svg) is bound to the GeometryDrawing.Brush
property.
The controls such as SvgViewbox and SvgCanvas do handle conversions, so we could support background conversion here including support for async/await procedures in .NET45 versions.
That's a good solution! Then the gui would be much more response! Actually I have more than 4seconds until the Page has been loaded..
Just for information, do you have animations in the SVG files?
It is very simple. I made a Binding
in code behind between a public DependencyProperty
of the customControl
and BrushProperty
. Then in my XAML Style definition, I have a Storyboard
to animate the DependencyProperty
foreach (Drawing drawing in drawings)
{
if (drawing is GeometryDrawing geometryDrawing)
{
BindingOperations.SetBinding(geometryDrawing, GeometryDrawing.BrushProperty, fillBinding);
}
}
I do not understand exactly what you want to tell me
I think we need more documentations of the library features since mode is being added. Basically, you can modify the SVG DOM if the Svg Document object is exposed. It is an instance of XmlDocument, so you can query, modify etc. The statement is how to make it useful for developers using the controls in their applications.
Ah ok! I have found another way to solve my problem with only 1 svg and without any layers.
Personally, I think the layer could make the work clearer. Design tools allow layer creation so the flow will be natural.
It is very simple. I made a
Binding
in code behind between a publicDependencyProperty
of the...
You only need more access to the created Drawing objects, will commit those changes soon.
@dojo90 Please see if this commit addresses your needs 6eec55531b23d76a9fc3ebf1b3b1511e0cbe2ee4
I think we need more documentations of the library features since mode is being added. Basically, you can modify the SVG DOM if the Svg Document object is exposed. It is an instance of XmlDocument, so you can query, modify etc.
But that means you have to 'redraw'/'render' the svg after modifing the source. For my personal needs, it's enough to get access to each object of the rendered svg. Maybe other people want to modify the svg via their app. With your last commit https://github.com/ElinamLLC/SharpVectors/commit/6eec55531b23d76a9fc3ebf1b3b1511e0cbe2ee4 a developer has access to all the rendered objects. That is exactly what I was asking for 😎 👍
I just wonder if it is also possible to specify the contour, since currently only the background (of the svg) is bound to the
GeometryDrawing.Brush
property.
Could you please take a look at this quote
It is very simple. I made a
Binding
in code behind between a publicDependencyProperty
of thecustomControl
andBrushProperty
. Then in my XAML Style definition, I have aStoryboard
to animate theDependencyProperty
foreach (Drawing drawing in drawings) { if (drawing is GeometryDrawing geometryDrawing) { BindingOperations.SetBinding(geometryDrawing, GeometryDrawing.BrushProperty, fillBinding); } }
@dojo90 Hi, I am looking for a way to change svg foreground color and I just saw your solution in here. Thanks for your idea, it is help me a lot, but I don't really understand how to bind a non-DependencyProperty to my ViewModel (Child? Drawings?). I can access SvgViewbox via x:Name but I will more like to access it with ViewModel (MVVM), could you please give me more hint? Thanks.
After a couple research, I found my solution. It is reference to @dojo90 's sample code, but it don't need to add code on code-behind. Just create a custom dependency property and bind it.
public class MySvgViewbox : SvgViewbox
{
public static readonly DependencyProperty BrushProperty =
DependencyProperty.Register("Brush", typeof(Brush),
typeof(MySvgViewbox), new PropertyMetadata(
Brushes.BlueViolet));
public Brush Brush
{
get { return (Brush)GetValue(BrushProperty); }
set { SetValue(BrushProperty, value); }
}
protected override void OnSettingsChanged()
{
base.OnSettingsChanged();
IList<Drawing> drawings = ((SvgDrawingCanvas)Child).DrawObjects;
foreach (Drawing drawing in drawings)
{
if (drawing is GeometryDrawing geometryDrawing)
{
Binding b = new Binding("Brush")
{
Source = this,
Mode = BindingMode.OneWay
};
BindingOperations.SetBinding(geometryDrawing, GeometryDrawing.BrushProperty, b);
}
}
}
}
Sorry to reserruct this issue, but is there a plan to include this feature into SvgViewbox?
If so, you might find the folllowing implementation useful as it also allows for overriding the svg's stroke color.
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);
}
}
}
}
}
@stojy Do you mean the binding operations suggested by @Lak4CYUT?
The original thread was on making the drawing in SvgDrawingCanvas
public, which really is not an issue since SvgDrawingCanvas
does not perform conversion by itself.
So, @Lak4CYUT post should be in a different thread to be addressed properly.
You can post a new issue with your suggestions and reference this one. This is similar to the discussion here Change svg image colors at runtime?.
@paulushub, that's correct.. I was referring to @Lak4CYUT's binding suggestion. I'll make a fresh posting as suggested.
Actually I want to change the color of the svg via XAML or code behind. Due to the
private
modifier, it is not possible to access the objects (see: https://github.com/ElinamLLC/SharpVectors/blob/master/Source/SharpVectorRuntimeWpf/SvgDrawingCanvas.cs#L49).I found a possibility to get it working via reflection:
Is there a special reason why they are
private
?