question

JefryPozo avatar image
0 Votes"
JefryPozo asked JefryPozo edited

Property change not fired on bindable property defined at page level

I have a custom ContentPage with a BindableProperty called ActionBarMenu but somehow it looks like bindings are not working if you set them at the page level.

I'm trying to achieve something like the TitleView or the ToolbarItems of a page:

 <controls:ContentPageWithActionBar.ActionBarMenu>        
         <actionBarMenu:Menu
             MenuDismissedCommand="{Binding DismissSelectionCommand}"
             ToolbarOffsetChangedCommand="{Binding ToolbarOffsetChangedCommand}">            
             <actionBarMenu:Menu.MenuItems>
                 <actionBarMenu:MenuItem Title="My title" TooltipText="This is my title" />
                 <actionBarMenu:MenuItem Title="My title2" TooltipText="This is my title 20" />
                 <actionBarMenu:MenuItem Title="My title3" TooltipText="This is my title 3" />
             </actionBarMenu:Menu.MenuItems>
         </actionBarMenu:Menu>
     </controls:ContentPageWithActionBar.ActionBarMenu>

The property changed is not firing for both events, but I noticed that if I set the control as a child of another view then it's working fine.

This is the Menu.cs file:

 public class Menu : View
     {
         public static readonly BindableProperty MenuItemsProperty = BindableProperty.CreateAttached(
             "MenuItems",
             typeof(ICollection<MenuItem>),
             typeof(Menu),
             null,
             BindingMode.TwoWay,
             defaultValueCreator: bindable =>
             {
                 return new Collection<MenuItem>();
             } 
         );       
    
         public static void SetMenuItems(BindableObject bindable, ICollection<MenuItem> value)
         {
             bindable.SetValue(MenuItemsProperty, value);
         }
    
         public static ICollection<MenuItem> GetMenuItems(BindableObject bindable)
         {
             return (ICollection<MenuItem>) bindable.GetValue(MenuItemsProperty);
         }
    
         public static readonly BindableProperty MenuDismissedCommandProperty = BindableProperty.CreateAttached(
             "MenuDismissedCommand",
             typeof(ICommand),
             typeof(Menu),
             null,
             propertyChanged: MenuDismissedCommandChanged
         );
    
         private static void MenuDismissedCommandChanged(BindableObject bindable, object oldvalue, object newvalue)
         {
                
         }
    
         public static void SetMenuDismissedCommand(BindableObject bindable, ICommand value)
         {
             bindable.SetValue(MenuDismissedCommandProperty, value);
         }
    
         public static ICommand GetMenuDismissedCommand(BindableObject bindable)
         {
             return (ICommand) bindable.GetValue(MenuDismissedCommandProperty);
         }
            
         public static readonly BindableProperty ToolbarOffsetChangedCommandProperty = BindableProperty.CreateAttached(
             "ToolbarOffsetChangedCommand",
             typeof(ICommand),
             typeof(Menu),
             null,
             propertyChanged: ToolbarOffsetChangedCommandChanged
         );
    
         private static void ToolbarOffsetChangedCommandChanged(BindableObject bindable, object oldvalue, object newvalue)
         {
                
         }
    
         public static void SetToolbarOffsetChangedCommand(BindableObject bindable, ICommand value)
         {
             bindable.SetValue(ToolbarOffsetChangedCommandProperty, value);
         }
    
         public static ICommand GetToolbarOffsetChangedCommand(BindableObject bindable)
         {
             return (ICommand) bindable.GetValue(ToolbarOffsetChangedCommandProperty);
         }
     }


And here is the custom ContentPage:

 public class ContentPageWithActionBar : ContentPage
     {
         public static readonly BindableProperty ActionBarMenuProperty = BindableProperty.CreateAttached(
             "ActionBarMenu",
             typeof(ActionBarMenu.Menu),
             typeof(ContentPageWithActionBar),
             null,
             propertyChanged: OnActionBarMenuChanged
         );
    
         public static void SetActionBarMenu(BindableObject bindable, ActionBarMenu.Menu value)
         {
             bindable.SetValue(ActionBarMenuProperty, value);
         }
    
         public static ActionBarMenu.Menu GetActionBarMenu(BindableObject bindable)
         {
             return (ActionBarMenu.Menu) bindable.GetValue(ActionBarMenuProperty);
         }
    
         static void OnActionBarMenuChanged(BindableObject bindable, object oldValue, object newValue)
         {
             if (bindable != null)
             {
                    
             }
         }
   }
 }





dotnet-xamarin
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

JefryPozo avatar image
0 Votes"
JefryPozo answered JefryPozo edited

Looks like the binding wasn't fired because the BindingContext was null, and this was solved by binding the BindingContext to the context of the content page.

 BindingContext="{Binding Path=BindingContext, Source={x:Reference nameofcontentpage}}

With that change the binding started working :)


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.