@implements IDisposable @inject IJSRuntime JSRuntime @Model?.Name @code { [Parameter, EditorRequired] public NodeModel Model { get; set; } = null!; [Parameter] public EventCallback DoubleClick { get; set; } [Parameter] public EventCallback OnClick { get; set; } [CascadingParameter] protected bool MapIsActive { get; set; } [Parameter] public bool ShowName { get; set; } [Parameter] public EditorState EditorState { get; set; } private ElementReference circleRef; private ElementReference textRef; private ElementReference circleErrorRef; private DotNetObjectReference DotNetObj = null!; private bool IsError = false; private bool IsSetting => EditorState == EditorState.NavigationEdit || EditorState == EditorState.CreateStraighEdge || EditorState == EditorState.CreateCurveEdge || EditorState == EditorState.CreateDoubleCurveEdge || EditorState == EditorState.View; protected override async Task OnAfterRenderAsync(bool firstRender) { await base.OnAfterRenderAsync(firstRender); if (!firstRender) return; DotNetObj = DotNetObjectReference.Create(this); await JSRuntime.InvokeVoidAsync("AddMouseDownEventListener", DotNetObj, circleRef, nameof(OnMouseDown), false); await UpdatePosition(Model.X, Model.Y); await JSRuntime.InvokeVoidAsync("ElementSetAttribute", circleErrorRef, "visibility", "hidden"); } public override async Task SetParametersAsync(ParameterView parameters) { bool updateNode = false; if (parameters.TryGetValue(nameof(Model), out NodeModel? model) && ((Model?.Id ?? Guid.Empty) != (model?.Id ?? Guid.Empty))) { if (Model != null) { Model.PositionChanged -= Model_PositionChanged; Model.ActivedChanged -= ActivedChanged; Model.ErrorChanged -= ErrorChanged; } if (model != null) { updateNode = true; model.PositionChanged += Model_PositionChanged; model.ActivedChanged += ActivedChanged; model.ErrorChanged += ErrorChanged; } } await base.SetParametersAsync(parameters); if (updateNode && model != null) await UpdatePosition(model.X, model.Y); } private async void Model_PositionChanged() => await UpdatePosition(Model.X, Model.Y); [JSInvokable] public async Task OnMouseDown(int button, bool altKey, bool ctrlKey, bool shiftKey) => await OnClick.InvokeAsync(Model); private async Task UpdatePosition(double x, double y) { await JSRuntime.InvokeVoidAsync("SetNodePosition", circleRef, textRef, x, y); if (IsError) await JSRuntime.InvokeVoidAsync("SetNodePosition", circleErrorRef, textRef, x, y); } private async void ActivedChanged(bool state) => await JSRuntime.InvokeVoidAsync(state ? "AddSelected" : "RemoveSelected", circleRef); private async void ErrorChanged(bool state) { IsError = state; await JSRuntime.InvokeVoidAsync("ElementSetAttribute", circleErrorRef, "visibility", state ? "visible" : "hidden"); if (IsError) await JSRuntime.InvokeVoidAsync("SetNodePosition", circleErrorRef, textRef, Model.X, Model.Y); } public void Dispose() { if (Model != null) { Model.PositionChanged -= Model_PositionChanged; Model.ActivedChanged -= ActivedChanged; Model.ErrorChanged -= ErrorChanged; } if (DotNetObj != null) DotNetObj.Dispose(); GC.SuppressFinalize(this); } }