use a BP for QueryAttributes (#6569)
authorStephane Delcroix <stephane@delcroix.org>
Wed, 19 Jun 2019 08:12:22 +0000 (10:12 +0200)
committerGitHub <noreply@github.com>
Wed, 19 Jun 2019 08:12:22 +0000 (10:12 +0200)
* use a BP for QueryAttributes

* Update Xamarin.Forms.Core/Shell/ShellContent.cs

Xamarin.Forms.Core/BindableProperty.cs
Xamarin.Forms.Core/Shell/Shell.cs
Xamarin.Forms.Core/Shell/ShellContent.cs

index 9ea9dfe..e1f759d 100644 (file)
@@ -60,21 +60,21 @@ namespace Xamarin.Forms
                                                                 CoerceValueDelegate coerceValue = null, BindablePropertyBindingChanging bindingChanging = null, bool isReadOnly = false, CreateDefaultValueDelegate defaultValueCreator = null)
                {
                        if (propertyName == null)
-                               throw new ArgumentNullException("propertyName");
+                               throw new ArgumentNullException(nameof(propertyName));
                        if (ReferenceEquals(returnType, null))
-                               throw new ArgumentNullException("returnType");
+                               throw new ArgumentNullException(nameof(returnType));
                        if (ReferenceEquals(declaringType, null))
-                               throw new ArgumentNullException("declaringType");
+                               throw new ArgumentNullException(nameof(declaringType));
 
                        // don't use Enum.IsDefined as its redonkulously expensive for what it does
                        if (defaultBindingMode != BindingMode.Default && defaultBindingMode != BindingMode.OneWay && defaultBindingMode != BindingMode.OneWayToSource && defaultBindingMode != BindingMode.TwoWay && defaultBindingMode != BindingMode.OneTime)
-                               throw new ArgumentException($"Not a valid type of BindingMode. Property: {returnType} {declaringType.Name}.{propertyName}. Default binding mode: {defaultBindingMode}", "defaultBindingMode");
+                               throw new ArgumentException($"Not a valid type of BindingMode. Property: {returnType} {declaringType.Name}.{propertyName}. Default binding mode: {defaultBindingMode}", nameof(defaultBindingMode));
 
                        if (defaultValue == null && Nullable.GetUnderlyingType(returnType) == null && returnType.GetTypeInfo().IsValueType)
                                defaultValue = Activator.CreateInstance(returnType);
 
                        if (defaultValue != null && !returnType.IsInstanceOfType(defaultValue))
-                               throw new ArgumentException($"Default value did not match return type. Property: {returnType} {declaringType.Name}.{propertyName} Default value type: {defaultValue.GetType().Name}, ", "defaultValue");
+                               throw new ArgumentException($"Default value did not match return type. Property: {returnType} {declaringType.Name}.{propertyName} Default value type: {defaultValue.GetType().Name}, ", nameof(defaultValue));
 
                        if (defaultBindingMode == BindingMode.Default)
                                defaultBindingMode = BindingMode.OneWay;
index d34983f..3cc8fb6 100644 (file)
@@ -490,7 +490,7 @@ namespace Xamarin.Forms
                        if (baseShellItem != null)
                                baseShellItem.ApplyQueryAttributes(filteredQuery);
                        else if (isLastItem)
-                               ShellContent.ApplyQueryAttributes(element, query);
+                               element.SetValue(ShellContent.QueryAttributesProperty, query);
                }
 
                ShellNavigationState GetNavigationState(ShellItem shellItem, ShellSection shellSection, ShellContent shellContent, IReadOnlyList<Page> sectionStack)
index 0ca9d55..547767e 100644 (file)
@@ -28,6 +28,9 @@ namespace Xamarin.Forms
                public static readonly BindableProperty ContentTemplateProperty =
                        BindableProperty.Create(nameof(ContentTemplate), typeof(DataTemplate), typeof(ShellContent), null, BindingMode.OneTime);
 
+               internal static readonly BindableProperty QueryAttributesProperty =
+                       BindableProperty.CreateAttached("QueryAttributes", typeof(IDictionary<string, string>), typeof(ShellContent), defaultValue: null, propertyChanged: OnQueryAttributesPropertyChanged);
+
                public MenuItemCollection MenuItems => (MenuItemCollection)GetValue(MenuItemsProperty);
 
                public object Content {
@@ -65,10 +68,8 @@ namespace Xamarin.Forms
                        if (result == null)
                                throw new InvalidOperationException($"No Content found for {nameof(ShellContent)}, Title:{Title}, Route {Route}");
 
-                       if (_delayedQueryParams != null && result  != null) {
-                               ApplyQueryAttributes(result, _delayedQueryParams);
-                               _delayedQueryParams = null;
-                       }
+                       if (GetValue(QueryAttributesProperty) is IDictionary<string, string> delayedQueryParams)
+                               result.SetValue(QueryAttributesProperty, delayedQueryParams);
 
                        return result;
                }
@@ -81,17 +82,14 @@ namespace Xamarin.Forms
                IList<Element> _logicalChildren = new List<Element>();
                ReadOnlyCollection<Element> _logicalChildrenReadOnly;
 
-               public ShellContent()
-               {
-                       ((INotifyCollectionChanged)MenuItems).CollectionChanged += MenuItemsCollectionChanged;
-               }
+               public ShellContent() => ((INotifyCollectionChanged)MenuItems).CollectionChanged += MenuItemsCollectionChanged;
 
 
                internal override ReadOnlyCollection<Element> LogicalChildrenInternal => _logicalChildrenReadOnly ?? (_logicalChildrenReadOnly = new ReadOnlyCollection<Element>(_logicalChildren));
 
                Page ContentCache
                {
-                       get { return _contentCache; }
+                       get => _contentCache;
                        set
                        {
                                _contentCache = value;
@@ -159,20 +157,22 @@ namespace Xamarin.Forms
                                        OnChildRemoved(el);
                }
 
-               IDictionary<string, string> _delayedQueryParams;
                internal override void ApplyQueryAttributes(IDictionary<string, string> query)
                {
                        base.ApplyQueryAttributes(query);
-                       ApplyQueryAttributes(this, query);
+                       SetValue(QueryAttributesProperty, query);
 
-                       if (Content == null) {
-                               _delayedQueryParams = query;
-                               return;
-                       }
-                       ApplyQueryAttributes(Content as Page, query);
+                       if (Content is BindableObject bindable)
+                               bindable.SetValue(QueryAttributesProperty, query);
+               }
+
+               static void OnQueryAttributesPropertyChanged(BindableObject bindable, object oldValue, object newValue)
+               {
+                       if (newValue is IDictionary<string, string> query)
+                               ApplyQueryAttributes(bindable, query);
                }
 
-               internal static void ApplyQueryAttributes(object content, IDictionary<string, string> query)
+               static void ApplyQueryAttributes(object content, IDictionary<string, string> query)
                {
                        if (content is IQueryAttributable attributable)
                                attributable.ApplyQueryAttributes(query);
@@ -201,4 +201,4 @@ namespace Xamarin.Forms
                        }
                }
        }
-}
\ No newline at end of file
+}