diff --git a/Source/Basic Shapes/SvgVisualElement.cs b/Source/Basic Shapes/SvgVisualElement.cs
index a9798705c7d1900adbd313fe6029bfecca7db9b1..cb6b404b3cafae271763351b80b3f4daab0a9e8a 100644
--- a/Source/Basic Shapes/SvgVisualElement.cs
+++ b/Source/Basic Shapes/SvgVisualElement.cs
@@ -61,7 +61,6 @@ namespace Svg
set { this.Attributes["clip-rule"] = value; }
}
-
///
/// Gets the associated if one has been specified.
///
@@ -72,7 +71,6 @@ namespace Svg
set { this.Attributes["filter"] = value; }
}
-
///
/// Gets or sets a value to determine if anti-aliasing should occur when the element is being rendered.
///
diff --git a/Source/Document Structure/SvgDefinitionList.cs b/Source/Document Structure/SvgDefinitionList.cs
index bd39d971b51de5823d58872100e8c7319d8bd6b5..9342773ef06a40b4cb4b0557b87d5a441811b108 100644
--- a/Source/Document Structure/SvgDefinitionList.cs
+++ b/Source/Document Structure/SvgDefinitionList.cs
@@ -26,7 +26,6 @@ namespace Svg
// Do nothing. Children should NOT be rendered.
}
-
public override SvgElement DeepCopy()
{
return DeepCopy();
diff --git a/Source/Painting/SvgGradientServer.cs b/Source/Painting/SvgGradientServer.cs
index 83070db57b4bcb51dc2148583fac318278d65fad..e84fd4bb39dcdfbac799f239e04bddb56b91aeff 100644
--- a/Source/Painting/SvgGradientServer.cs
+++ b/Source/Painting/SvgGradientServer.cs
@@ -88,7 +88,7 @@ namespace Svg
///
/// Gets or sets another gradient fill from which to inherit the stops from.
///
- [SvgAttributeAttribute("href")]
+ [SvgAttribute("href")]
public SvgGradientServer InheritGradient
{
get { return this._inheritGradient; }
diff --git a/Source/SvgAttributeCollection.cs b/Source/SvgAttributeCollection.cs
index 8929e51ef235243ad6049ac8dfe28d56e2b94c26..0c504d07e5eee5237ed1a592176644159938c75a 100644
--- a/Source/SvgAttributeCollection.cs
+++ b/Source/SvgAttributeCollection.cs
@@ -87,7 +87,90 @@ namespace Svg
public new object this[string attributeName]
{
get { return this.GetInheritedAttribute(attributeName); }
- set { base[attributeName] = value; }
+ set
+ {
+ if(base.ContainsKey(attributeName))
+ {
+ var oldVal = base[attributeName];
+ base[attributeName] = value;
+ if(oldVal != value) OnAttributeChanged(attributeName, value);
+ }
+ else
+ {
+ base[attributeName] = value;
+ OnAttributeChanged(attributeName, value);
+ }
+ }
+ }
+
+ ///
+ /// Fired when an Atrribute has changed
+ ///
+ public event EventHandler AttributeChanged;
+
+ protected void OnAttributeChanged(string attribute, object value)
+ {
+ var handler = AttributeChanged;
+ if(handler != null)
+ {
+ handler(this._owner, new AttributeEventArgs { Attribute = attribute, Value = value });
+ }
+ }
+ }
+
+
+ ///
+ /// A collection of Custom Attributes
+ ///
+ public sealed class SvgCustomAttributeCollection : Dictionary
+ {
+ private SvgElement _owner;
+
+ ///
+ /// Initialises a new instance of a with the given as the owner.
+ ///
+ /// The owner of the collection.
+ public SvgCustomAttributeCollection(SvgElement owner)
+ {
+ this._owner = owner;
+ }
+
+ ///
+ /// Gets the attribute with the specified name.
+ ///
+ /// A containing the attribute name.
+ /// The attribute value associated with the specified name; If there is no attribute the parent's value will be inherited.
+ public new string this[string attributeName]
+ {
+ get { return base[attributeName]; }
+ set
+ {
+ if(base.ContainsKey(attributeName))
+ {
+ var oldVal = base[attributeName];
+ base[attributeName] = value;
+ if(oldVal != value) OnAttributeChanged(attributeName, value);
+ }
+ else
+ {
+ base[attributeName] = value;
+ OnAttributeChanged(attributeName, value);
+ }
+ }
+ }
+
+ ///
+ /// Fired when an Atrribute has changed
+ ///
+ public event EventHandler AttributeChanged;
+
+ protected void OnAttributeChanged(string attribute, object value)
+ {
+ var handler = AttributeChanged;
+ if(handler != null)
+ {
+ handler(this._owner, new AttributeEventArgs { Attribute = attribute, Value = value });
+ }
}
}
}
\ No newline at end of file
diff --git a/Source/SvgDocument.cs b/Source/SvgDocument.cs
index 52ef7be1507d565b471cb28d3702027800c0d2ec..81c98760c29cb2d85c7f3321baf2ab45e913e1e3 100644
--- a/Source/SvgDocument.cs
+++ b/Source/SvgDocument.cs
@@ -44,6 +44,17 @@ namespace Svg
return _idManager;
}
}
+
+ ///
+ /// Overwrites the current IdManager with a custom implementation.
+ /// Be careful with this: If elements have been inserted into the document before,
+ /// you have to take care that the new IdManager also knows of them.
+ ///
+ ///
+ public void OverwriteIdManager(SvgElementIdManager manager)
+ {
+ _idManager = manager;
+ }
///
/// Gets or sets the Pixels Per Inch of the rendered image.
diff --git a/Source/SvgElement.cs b/Source/SvgElement.cs
index b4c8fb1a4843033cde1398d60676b067c06247a1..daad734e6fd02abf375f8cbc0bacf8314892a481 100644
--- a/Source/SvgElement.cs
+++ b/Source/SvgElement.cs
@@ -41,7 +41,7 @@ namespace Svg
private SvgElementCollection _children;
private static readonly object _loadEventKey = new object();
private Matrix _graphicsMatrix;
- private Dictionary _customAttributes;
+ private SvgCustomAttributeCollection _customAttributes;
///
/// Gets the name of the element.
@@ -121,24 +121,20 @@ namespace Svg
///
public virtual SvgDocument OwnerDocument
{
- get
- {
- if (Parent == null)
- {
- if (this is SvgDocument)
- {
- return (SvgDocument)this;
- }
- else
- {
- return null;
- }
- }
- else
- {
- return Parent.OwnerDocument;
- }
- }
+ get
+ {
+ if (this is SvgDocument)
+ {
+ return this as SvgDocument;
+ }
+ else
+ {
+ if(this.Parent != null)
+ return Parent.OwnerDocument;
+ else
+ return null;
+ }
+ }
}
///
@@ -157,7 +153,10 @@ namespace Svg
}
}
- public Dictionary CustomAttributes
+ ///
+ /// Gets a collection of custom attributes
+ ///
+ public SvgCustomAttributeCollection CustomAttributes
{
get { return this._customAttributes; }
}
@@ -301,7 +300,11 @@ namespace Svg
this._children = new SvgElementCollection(this);
this._eventHandlers = new EventHandlerList();
this._elementName = string.Empty;
- this._customAttributes = new Dictionary();
+ this._customAttributes = new SvgCustomAttributeCollection(this);
+
+ //subscribe to attribute events
+ Attributes.AttributeChanged += Attributes_AttributeChanged;
+ CustomAttributes.AttributeChanged += Attributes_AttributeChanged;
//find svg attribute descriptions
_svgPropertyAttributes = from PropertyDescriptor a in TypeDescriptor.GetProperties(this)
@@ -316,6 +319,12 @@ namespace Svg
}
+ //dispatch attribute event
+ void Attributes_AttributeChanged(object sender, AttributeEventArgs e)
+ {
+ OnAttributeChanged(e);
+ }
+
public virtual void InitialiseFromXML(XmlTextReader reader, SvgDocument document)
{
throw new NotImplementedException();
@@ -628,6 +637,20 @@ namespace Svg
return newObj;
}
+
+ ///
+ /// Fired when an Atrribute of this Element has changed
+ ///
+ public event EventHandler AttributeChanged;
+
+ protected void OnAttributeChanged(AttributeEventArgs args)
+ {
+ var handler = AttributeChanged;
+ if(handler != null)
+ {
+ handler(this, args);
+ }
+ }
#region graphical EVENTS
@@ -640,7 +663,7 @@ namespace Svg
onmouseup = ""
onmouseover = ""
onmousemove = ""
- onmouseout = ""
+ onmouseout = ""
*/
///
@@ -662,6 +685,25 @@ namespace Svg
caller.RegisterAction(rpcID + "onmouseout", OnMouseOut);
}
}
+
+ ///
+ /// Use this method to provide your implementation ISvgEventCaller to unregister Actions
+ ///
+ ///
+ public void UnregisterEvents(ISvgEventCaller caller)
+ {
+ if (caller != null && !string.IsNullOrWhiteSpace(this.ID))
+ {
+ var rpcID = this.ID + "/";
+
+ caller.UnregisterAction(rpcID + "onclick");
+ caller.UnregisterAction(rpcID + "onmousedown");
+ caller.UnregisterAction(rpcID + "onmouseup");
+ caller.UnregisterAction(rpcID + "onmousemove");
+ caller.UnregisterAction(rpcID + "onmouseover");
+ caller.UnregisterAction(rpcID + "onmouseout");
+ }
+ }
[SvgAttribute("onclick")]
public event EventHandler Click;
@@ -774,6 +816,15 @@ namespace Svg
#endregion graphical EVENTS
}
+
+ ///
+ /// Describes the Attribute which was set
+ ///
+ public class AttributeEventArgs : EventArgs
+ {
+ public string Attribute;
+ public object Value;
+ }
//deriving class registers event actions and calls the actions if the event occurs
public interface ISvgEventCaller
@@ -783,6 +834,7 @@ namespace Svg
void RegisterAction(string rpcID, Action action);
void RegisterAction(string rpcID, Action action);
void RegisterAction(string rpcID, Action action);
+ void UnregisterAction(string rpcID);
}
///
diff --git a/Source/SvgElementCollection.cs b/Source/SvgElementCollection.cs
index 206984855ae4d5813d6228e4b7bee0f7a3fad691..0d3b35f4fdf1d88ce45ccb5c23979a160f1f668a 100644
--- a/Source/SvgElementCollection.cs
+++ b/Source/SvgElementCollection.cs
@@ -78,7 +78,7 @@ namespace Svg
{
if (this._owner.OwnerDocument != null)
{
- this._owner.OwnerDocument.IdManager.Add(item);
+ item.ApplyRecursive(this._owner.OwnerDocument.IdManager.Add);
}
item._parent = this._owner;
@@ -132,7 +132,7 @@ namespace Svg
if (this._owner.OwnerDocument != null)
{
- this._owner.OwnerDocument.IdManager.Remove(item);
+ item.ApplyRecursive(this._owner.OwnerDocument.IdManager.Remove);
}
}
}
diff --git a/Source/SvgElementIdManager.cs b/Source/SvgElementIdManager.cs
index 1956501922db0dd3df0d6d795bd8e19ee76ed627..2520f799664d411394e8033b0734b0947393402a 100644
--- a/Source/SvgElementIdManager.cs
+++ b/Source/SvgElementIdManager.cs
@@ -52,6 +52,8 @@ namespace Svg
this.EnsureValidId(element.ID);
this._idValueMap.Add(element.ID, element);
}
+
+ OnAdded(element);
}
///
@@ -64,6 +66,8 @@ namespace Svg
{
this._idValueMap.Remove(element.ID);
}
+
+ OnRemoved(element);
}
///
@@ -101,5 +105,32 @@ namespace Svg
this._document = document;
this._idValueMap = new Dictionary();
}
+
+ public event EventHandler ElementAdded;
+ public event EventHandler ElementRemoved;
+
+ protected void OnAdded(SvgElement element)
+ {
+ var handler = ElementAdded;
+ if(handler != null)
+ {
+ handler(this._document, new SvgElementEventArgs{ Element = element });
+ }
+ }
+
+ protected void OnRemoved(SvgElement element)
+ {
+ var handler = ElementRemoved;
+ if(handler != null)
+ {
+ handler(this._document, new SvgElementEventArgs{ Element = element });
+ }
+ }
+
+ }
+
+ public class SvgElementEventArgs : EventArgs
+ {
+ public SvgElement Element;
}
}
\ No newline at end of file
diff --git a/Source/SvgExtentions.cs b/Source/SvgExtentions.cs
index 589a33ca6574816399beb1f96eb5b0b733cd863b..7f77a66adfa406f5cc332423b2d9dedd863de628 100644
--- a/Source/SvgExtentions.cs
+++ b/Source/SvgExtentions.cs
@@ -52,5 +52,16 @@ namespace Svg
{
return element.CustomAttributes.ContainsKey(name) && !string.IsNullOrEmpty(element.CustomAttributes[name]);
}
+
+ public static void ApplyRecursive(this SvgElement elem, Action action)
+ {
+ action(elem);
+
+ foreach (var element in elem.Children)
+ {
+ if(!(elem is SvgDocument))
+ element.ApplyRecursive(action);
+ }
+ }
}
}