Search code examples
c#xamlparametersuwpcommandbar

Move Command Bar Buttons Click Events from frame out to MainPage UWP


I have to move a CommandBar from a page loaded into a frame in the MainPage, where the NavigationView is present. I implemented the visibility of an AppBarButton when I load the page where the CommandBar was located. How can I refer to the parameter passed to the page for use in the AppBarButton which is now in mainPage?

The AppBarButton deletes an object from a database, to delete it uses the ID of the object that is passed to the page when the object is selected.

I was thinking of using the OnNavigatedTo method but I'm not loading MainPAge because it's already there when I have to pass the parameter

This is the code of the page where the AppBarButton was present

public sealed partial class DetailsPage : Page
{
   DatabaseHelperClass Db_Helper = new DatabaseHelperClass();
   FFSystems currentSystem = new FFSystems();

   private void DeleteSystem_Click(object sender, RoutedEventArgs e)
   {
       Db_Helper.DeleteFFSystem(currentSystem.ID);//Delete selected DB contact Id. 
       Frame.Navigate(typeof(Home));
   }
}

I have to move DeleteSystem_Click event to the MainPage AppBarButton that appear when I move to this page form navigationView home.

This is the XAML of the CommandBar in MainPage.xaml

<Grid.Resources>
      <Converter:VisibleOrNotInfoSystem x:Key="cvtDetails" />
</Grid.Resources>
<NavigationView x:Name="navView">
       ...
    </NavigationView>
    <CommandBar DefaultLabelPosition="Right" 
                Grid.Row="0" 
                Style="{ThemeResource CommandBarRevealStyle}" 
                Background="Transparent" 
                Margin="0,30">
         <CommandBar.SecondaryCommands>
              <AppBarButton x:Name="DeleteSystem" 
                            Click="DeleteSystem_Click"
                            Label="Elimina Sistema" 
                            Visibility="{Binding ElementName=ContentFrame, Path=Content.BaseUri.AbsoluteUri, Converter={StaticResource cvtDetails}}"/>
          </CommandBar.SecondaryCommands>
    </CommandBar>

The AppBarButton DeleteSystem appear when frame of navigationView is on DetailsPage.xaml where the CommandBar was previously. To do that I use an IValueConverter:

public class VisibleOrNotInfoSystem : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        Uri uri = new Uri(value.ToString());
        if (uri != null)
        {
            if (uri.Equals("ms-appx:///Views/DetailsPage.xaml"))
            {
                return Visibility.Visible;
            }
         }
         return Visibility.Collapsed;
     }

     public object ConvertBack(object value, Type targetType, object parameter, string language)
     {
         throw new NotImplementedException();
     }

}

DetailsPage.xaml opens when i select a listViewItem from a listView, i pass the ID of the Item in DetailsPage, but now I have to pass the ID to the MainPage CommandBar.


Solution

  • If you want to display a command bar at the bottom of the whole application view, you can put it into <Page.BottomAppBar>. This way, even if you navigate to the DetailsPage within a frame, the CommandBar will display at the bottom of the page.

    So on details page you would do:

    <Page.BottomAppBar>
        <CommandBar ... />
    </Page.BottomAppBar>
    

    As an alternative, you could create a method in your MainPage that would return the AppBarButton itself:

    public AppBarButton GetDeleteButton()
    {
        return DeleteSystem;
    }
    

    Now you could access main page from the DetailsPage code:

    var rootFrame = Window.Current.Content as Frame;
    var mainPage = rootFrame.Content as MainPage;
    var button = mainPage.GetDeleteButton();
    

    And you can then attach the event you need in the OnNavigatedTo event of your DetailsPage:

    button.Click += DeleteSystem_Click;
    

    And of course don't forget to detach the event in the OnNavigatedFrom event:

    button.Click -= DeleteSystem_Click;