Hi there! I am looking for an event that fires when a pivot of a custom Grasshopper component changes its location on the canvas. I’ve tried the following events:
AttributesChanged - doesn’t fire
DisplayExpired - doesn’t fire
ObjectChanged - doesn’t fire
PreviewExpired - didn’t expect it to fire to begin with
I’ve also tried approaching this from the opposite direction by tapping into some events on the document and on the canvas:
doc.ContextChanged - doesn’t fire
doc.ModifiedChanged - not sure if relevant, but doesn’t fire
canvas.DragDrop - likely not relevant and doesn’t fire
canvas.Invalidated - fires way too often
canvas.Click - fires way too often
canvas.Move - doesn’t fire
canvas.LocationChanged - probably not relevant and doesn’t fire
I even tried inheriting from INotifyPropertyChanged, but obviously, the setter on the Pivot property doesn’t raise the PropertyChanged event, so this was a largely futile pursuit as well. Any thoughts?
For anyone else who will find this helpful. Based on the combined wisdom from @andheum and @Dani_Abalde, this is what I ended up with (works perfectly):
Here is my custom ComponentAttributes class:
public class CustomComponentAttributes : GH_ComponentAttributes
{
// Just to keep track of the old location (optional)
public PointF LastKnownPivot { get; set; }
public CustomComponentAttributes (IGH_Component comp) : base(comp)
{
this.LastKnownPivot = new PointF(this.Pivot.X, this.Pivot.Y);
}
public override PointF Pivot
{
get => base.Pivot;
set
{
base.Pivot = value;
// Raise custom event
OnPivotMoved(new ComponentMovedEventArgs(
this.Owner.InstanceGuid,
this.Owner.ComponentGuid,
this.LastKnownPivot,
this.Pivot));
}
}
// The custom event being raised from the Pivot setter
public event EventHandler PivotMoved;
public void OnPivotMoved(ComponentMovedEventArgs e)
{
EventHandler handler = PivotMoved;
handler?.Invoke(this, e);
this.LastKnownPivot = new PointF(this.Pivot.X, this.Pivot.Y);
}
}
Here are my custom event arguments (they can be whatever you want them to be):
public class ComponentMovedEventArgs : EventArgs
{
public Guid InstanceGuid { get; set; }
public Guid ComponentGuid { get; set; }
public PointF OldPivot { get; set; }
public PointF NewPivot { get; set; }
public ComponentMovedEventArgs(
Guid instanceGuid,
Guid componentGuid,
PointF oldPivot,
PointF newPivot)
{
this.InstanceGuid = instanceGuid;
this.ComponentGuid = componentGuid;
this.NewPivot = newPivot;
}
}
And this is my custom component:
public class MyCustomComponent : GH_Component
{
// Set custom attributes
public override void CreateAttributes()
{
Attributes = new CustomComponentAttributes(this);
((CustomComponentAttributes )Attributes).PivotMoved += CustomComponent_PivotMoved;
}
private void CustomComponent_PivotMoved(object sender, EventArgs e)
{
// Re-transmitting the event from inside the component itself
ComponentMovedEventArgs args = e as ComponentMovedEventArgs;
this.OnComponentMoved(args);
}
// Event exposed on the component itself
public event EventHandler ComponentMoved;
public void OnComponentMoved(ComponentMovedEventArgs e)
{
EventHandler handler = ComponentMoved;
handler?.Invoke(this, e);
}
}