| File: ElementTemplate.cs | Web Access |
| Project: src\src\Controls\src\Core\Controls.Core.csproj (Microsoft.Maui.Controls) |
#nullable disable using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using Microsoft.Maui.Controls.Internals; namespace Microsoft.Maui.Controls { /// <include file="../../docs/Microsoft.Maui.Controls/ElementTemplate.xml" path="Type[@FullName='Microsoft.Maui.Controls.ElementTemplate']/Docs/*" /> public class ElementTemplate : IElementDefinition { List<Action<object, ResourcesChangedEventArgs>> _changeHandlers; Element _parent; bool _canRecycle; // aka IsDeclarative [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] readonly Type _type; internal ElementTemplate() { } internal ElementTemplate( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type) : this() { if (type == null) throw new ArgumentNullException(nameof(type)); _canRecycle = true; _type = type; LoadTemplate = () => Activator.CreateInstance(type); } internal ElementTemplate(Func<object> loadTemplate) : this() => LoadTemplate = loadTemplate ?? throw new ArgumentNullException(nameof(loadTemplate)); public Func<object> LoadTemplate { get; set; } void IElementDefinition.AddResourcesChangedListener(Action<object, ResourcesChangedEventArgs> onchanged) { _changeHandlers = _changeHandlers ?? new List<Action<object, ResourcesChangedEventArgs>>(1); _changeHandlers.Add(onchanged); } internal bool CanRecycle => _canRecycle; [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] internal Type Type => _type; Element IElementDefinition.Parent { get { return _parent; } set { if (_parent == value) return; if (_parent != null) ((IElementDefinition)_parent).RemoveResourcesChangedListener(OnResourcesChanged); _parent = value; if (_parent != null) ((IElementDefinition)_parent).AddResourcesChangedListener(OnResourcesChanged); } } void IElementDefinition.RemoveResourcesChangedListener(Action<object, ResourcesChangedEventArgs> onchanged) { if (_changeHandlers == null) return; _changeHandlers.Remove(onchanged); } /// <include file="../../docs/Microsoft.Maui.Controls/ElementTemplate.xml" path="//Member[@MemberName='CreateContent']/Docs/*" /> public object CreateContent() { if (LoadTemplate == null) { // Returning a Label here instead of throwing an exception because HotReload may temporarily be in state // where the user is creating a template; this keeps everything else (which expects a result from CreateContent) // from crashing during that time. return new Label(); } if (this is DataTemplateSelector) throw new InvalidOperationException("Cannot call CreateContent directly on a DataTemplateSelector"); object item = LoadTemplate(); SetupContent(item); if (item is Element elem) elem.IsTemplateRoot = true; return item; } internal virtual void SetupContent(object item) { } void OnResourcesChanged(object sender, ResourcesChangedEventArgs e) { if (_changeHandlers == null) return; foreach (Action<object, ResourcesChangedEventArgs> handler in _changeHandlers) handler(this, e); } } }