using System.Reflection; namespace Sandbox.UI; public partial class Panel { /// /// True when a bind has changed and OnParametersSet call is pending a call /// bool templateBindsChanged = true; Task parametersSetTask; internal void ParametersChanged( bool immediately ) { templateBindsChanged = true; // task is still running if ( parametersSetTask != null && !parametersSetTask.IsCompleted ) return; if ( immediately ) { templateBindsChanged = false; parametersSetTask = OnParametersSetInternalAsync(); } } internal async Task OnParametersSetInternalAsync() { try { await OnParametersSetAsync(); } catch ( TaskCanceledException ) { return; } catch ( System.Exception e ) { Log.Warning( e, $"Exception in OnParametersSetAsync: {e.Message}" ); } if ( !IsValid ) return; try { OnParametersSet(); } catch ( System.Exception e ) { Log.Warning( e, $"Exception in OnParametersSet: {e.Message}" ); } StateHasChanged(); } /// /// Same as , but first tries to set the property on the panel object, then process any special properties such as class. /// /// public virtual void SetPropertyObject( string name, object value ) { var prop = GetType().GetProperty( name, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy ); if ( prop != null && prop.PropertyType.IsAssignableFrom( value?.GetType() ) ) { prop.SetValue( this, value ); return; } SetProperty( name, Convert.ToString( value ) ); } string previousPropertyClass; /// /// Set a property on the panel, such as special properties (class, id, style and value, etc.) and properties of the panel's C# class. /// /// name of the property to modify. /// Value to assign to the property. public virtual void SetProperty( string name, string value ) { if ( name == "id" ) { Id = value; return; } if ( name == "value" ) { StringValue = value; return; } if ( name == "class" ) { if ( !string.IsNullOrEmpty( previousPropertyClass ) ) { RemoveClass( previousPropertyClass ); } previousPropertyClass = value; AddClass( value ); return; } if ( name == "style" ) { Style.Set( value ); return; } SetAttribute( name, value ); Game.TypeLibrary.SetProperty( this, name, value ); } Dictionary Attributes; /// /// Used in templates, gets an attribute that was set in the template. /// public void SetAttribute( string k, string v ) { Attributes ??= new(); Attributes[k] = v; } /// /// Used in templates, try to get the attribute that was set in creation. /// public string GetAttribute( string k, string defaultIfNotFound = default ) { if ( Attributes == null ) return defaultIfNotFound; if ( Attributes.TryGetValue( k, out var v ) ) return v; return defaultIfNotFound; } /// /// Called after all templated panel binds have been set. /// protected virtual void OnParametersSet() { //Log.Info( $"{this} - OnParametersSet" ); } /// /// Called after all templated panel binds have been set. /// protected virtual Task OnParametersSetAsync() { return Task.CompletedTask; } /// /// Called by the templating system when an element has content between its tags. /// public virtual void SetContent( string value ) { } }