| File: Setter.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.Reflection; using System.Runtime.CompilerServices; using Microsoft.Maui.Controls.Internals; using Microsoft.Maui.Controls.Xaml; namespace Microsoft.Maui.Controls { /// <include file="../../docs/Microsoft.Maui.Controls/Setter.xml" path="Type[@FullName='Microsoft.Maui.Controls.Setter']/Docs/*" /> [ContentProperty(nameof(Value))] [ProvideCompiled("Microsoft.Maui.Controls.XamlC.SetterValueProvider")] [RequireService( [typeof(IValueConverterProvider), typeof(IXmlLineInfoProvider)])] public sealed class Setter : IValueProvider { /// <include file="../../docs/Microsoft.Maui.Controls/Setter.xml" path="//Member[@MemberName='TargetName']/Docs/*" /> public string TargetName { get; set; } /// <include file="../../docs/Microsoft.Maui.Controls/Setter.xml" path="//Member[@MemberName='Property']/Docs/*" /> public BindableProperty Property { get; set; } /// <include file="../../docs/Microsoft.Maui.Controls/Setter.xml" path="//Member[@MemberName='Value']/Docs/*" /> public object Value { get; set; } object IValueProvider.ProvideValue(IServiceProvider serviceProvider) { if (Property == null) throw new XamlParseException("Property not set", serviceProvider); var valueconverter = serviceProvider.GetService(typeof(IValueConverterProvider)) as IValueConverterProvider; MemberInfo minforetriever() { MemberInfo minfo = null; try { minfo = Property.DeclaringType.GetRuntimeProperty(Property.PropertyName); } catch (AmbiguousMatchException e) { throw new XamlParseException($"Multiple properties with name '{Property.DeclaringType}.{Property.PropertyName}' found.", serviceProvider, innerException: e); } if (minfo != null) return minfo; try { return Property.DeclaringType.GetRuntimeMethod("Get" + Property.PropertyName, new[] { typeof(BindableObject) }); } catch (AmbiguousMatchException e) { throw new XamlParseException($"Multiple methods with name '{Property.DeclaringType}.Get{Property.PropertyName}' found.", serviceProvider, innerException: e); } } object value = valueconverter.Convert(Value, Property.ReturnType, minforetriever, serviceProvider); Value = value; return this; } internal void Apply(BindableObject target, SetterSpecificity specificity) { if (target == null) throw new ArgumentNullException(nameof(target)); var targetObject = target; if (!string.IsNullOrEmpty(TargetName) && target is Element element) targetObject = element.FindByName(TargetName) as BindableObject ?? throw new XamlParseException($"Cannot resolve '{TargetName}' as Setter Target for '{target}'."); if (Property == null) return; if (Value is BindingBase binding) targetObject.SetBinding(Property, binding.Clone(), specificity); else if (Value is DynamicResource dynamicResource) targetObject.SetDynamicResource(Property, dynamicResource.Key, specificity); else if (Value is IList<VisualStateGroup> visualStateGroupCollection) targetObject.SetValue(Property, visualStateGroupCollection.Clone(), specificity); else targetObject.SetValue(Property, Value, specificity: specificity); } internal void UnApply(BindableObject target, SetterSpecificity specificity) { if (target == null) throw new ArgumentNullException(nameof(target)); var targetObject = target; if (!string.IsNullOrEmpty(TargetName) && target is Element element) targetObject = element.FindByName(TargetName) as BindableObject ?? throw new ArgumentNullException(nameof(targetObject)); if (Property == null) return; if (Value is BindingBase binding) targetObject.RemoveBinding(Property, specificity); else if (Value is DynamicResource dynamicResource) targetObject.RemoveDynamicResource(Property, specificity); targetObject.ClearValue(Property, specificity); } } }