| File: MarkupExtensions\RelativeSourceExtension.cs | Web Access |
| Project: src\src\Controls\src\Xaml\Controls.Xaml.csproj (Microsoft.Maui.Controls.Xaml) |
using System; using System.Reflection; namespace Microsoft.Maui.Controls.Xaml { [ContentProperty("Mode")] [AcceptEmptyServiceProvider] public sealed class RelativeSourceExtension : IMarkupExtension<RelativeBindingSource> { public RelativeBindingSourceMode Mode { get; set; } public int AncestorLevel { get; set; } public Type AncestorType { get; set; } RelativeBindingSource IMarkupExtension<RelativeBindingSource>.ProvideValue(IServiceProvider serviceProvider) { if (AncestorType != null) { RelativeBindingSourceMode actualMode; if (Mode != RelativeBindingSourceMode.FindAncestor && Mode != RelativeBindingSourceMode.FindAncestorBindingContext) { // Note to documenters: // This permits "{Binding Source={RelativeSource AncestorType={x:Type MyType}}}" syntax // where Mode hasn't been explicitly set, consistent with WPF. // Also, we assume FindAncestor is meant if the ancestor type is a visual // Element, otherwise assume FindAncestorBindingContext is intended. (The // mode can also be explicitly set in XAML) actualMode = typeof(Element).IsAssignableFrom(AncestorType) ? RelativeBindingSourceMode.FindAncestor : RelativeBindingSourceMode.FindAncestorBindingContext; } else { actualMode = Mode; } return new RelativeBindingSource(actualMode, AncestorType, AncestorLevel); } else if (Mode == RelativeBindingSourceMode.FindAncestor || Mode == RelativeBindingSourceMode.FindAncestorBindingContext) { throw new XamlParseException( $"{nameof(RelativeBindingSourceMode.FindAncestor)} and " + $"{nameof(RelativeBindingSourceMode.FindAncestorBindingContext)} " + $"require {nameof(AncestorType)}."); } else if (Mode == RelativeBindingSourceMode.Self) { return RelativeBindingSource.Self; } else if (Mode == RelativeBindingSourceMode.TemplatedParent) { return RelativeBindingSource.TemplatedParent; } else { throw new XamlParseException($"Invalid {nameof(Mode)}"); } } public object ProvideValue(IServiceProvider serviceProvider) { return (this as IMarkupExtension<RelativeBindingSource>).ProvideValue(serviceProvider); } } }