Add Dynamically shell items in Xamarin Forms with Crud functionality

Lidprodsky 101 Reputation points
2021-05-11T14:33:35.823+00:00

Hello coders,

I have an application that has a SettingsPage, in that page I have created a CRUD functionality.

The Idea is this: when I create an item with crud method, I want that Item to be displayed in the Menu.

The new item should be palced here: 95616-test.png

Can anyone help? In that case, could you give code example?

Any ideas are welcome!

Thanks

Developer technologies | .NET | Xamarin
0 comments No comments
{count} votes

Accepted answer
  1. Lidprodsky 101 Reputation points
    2021-05-12T06:40:24.07+00:00

    Hi,

    Thank you for you answer.

    I understand your logic but I cannot implement it to my project.. I am quite new in this. I'll share some code and hope that you can help.

    This is my AppShell.xaml

    <?xml version="1.0" encoding="UTF-8"?>
    <Shell xmlns="http://xamarin.com/schemas/2014/forms" 
           xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
           xmlns:local="clr-namespace:MyTestApplication.Views"
           xmlns:viewModels="clr-namespace:MyTestApplication.ViewModels;assembly=MyTestApplication"
           Title="MyTestApplication"
           x:Class="MyTestApplication.AppShell">
    
        <Shell.Resources>
            <ResourceDictionary>
                <Style x:Key="BaseStyle" TargetType="Element">
                    <Setter Property="Shell.BackgroundColor" Value="{StaticResource Primary}" />
                    <Setter Property="Shell.ForegroundColor" Value="White" />
                    <Setter Property="Shell.TitleColor" Value="White" />
                    <Setter Property="Shell.DisabledColor" Value="#B4FFFFFF" />
                    <Setter Property="Shell.UnselectedColor" Value="#95FFFFFF" />
                    <Setter Property="Shell.TabBarBackgroundColor" Value="{StaticResource Primary}" />
                    <Setter Property="Shell.TabBarForegroundColor" Value="White"/>
                    <Setter Property="Shell.TabBarUnselectedColor" Value="#95FFFFFF"/>
                    <Setter Property="Shell.TabBarTitleColor" Value="White"/>
                </Style>
                <Style TargetType="TabBar" BasedOn="{StaticResource BaseStyle}" />
                <Style TargetType="FlyoutItem" BasedOn="{StaticResource BaseStyle}" />
    
                <Style Class="MenuItemLayoutStyle" TargetType="Layout" ApplyToDerivedTypes="True">
                    <Setter Property="VisualStateManager.VisualStateGroups">
                        <VisualStateGroupList>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal">
                                    <VisualState.Setters>
                                        <Setter TargetName="FlyoutItemLabel" Property="Label.TextColor" Value="{StaticResource Primary}" />
                                    </VisualState.Setters>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateGroupList>
                    </Setter>
                </Style>
            </ResourceDictionary>
        </Shell.Resources>
    
    
        <FlyoutItem Title="Home" Icon="home.png">
                <ShellContent Route="MainPage" ContentTemplate="{DataTemplate local:MainPage}" />
            </FlyoutItem>
            <FlyoutItem Title="Settings" Icon="setting.png">
                <ShellContent Route="SettingsPage" ContentTemplate="{DataTemplate local:SettingsPage}" />
            </FlyoutItem>
    
        <MenuItem Icon="logout.png" Text="Logout" StyleClass="MenuItemLayoutStyle" Clicked="OnMenuItemClicked">
        </MenuItem>
    
        <TabBar >
            <ShellContent Route="LoginPage" ContentTemplate="{DataTemplate local:LoginPage}" />
        </TabBar>
    
    </Shell>
    

    This is my AppShell.xaml.cs

    public partial class AppShell : Xamarin.Forms.Shell
    {
    public List<ElseMenuItem> FlyoutItems { get; set; } = new List<ElseMenuItem>();

        public AppShell()
        {
            InitializeComponent();
        }
    
        private async void OnMenuItemClicked(object sender, EventArgs e)
        {
            await Shell.Current.GoToAsync("//LoginPage");
        }
    
    
    }
    

    This is my AddUrl.xaml.cs

    [XamlCompilation(XamlCompilationOptions.Compile)]
        public partial class AddUrl : ContentPage
        {
            private DbService _services;
            bool _isUpdate;
            int urlId;
            public AddUrl()
            {
                InitializeComponent();
                _services = new DbService(); // Initializing db service
                _isUpdate = false; // Boolean logic, if constructor calls without any Url parameters it is going to add new record
            }
    
            public AddUrl(Urls obj)
            {
                //If constructor calls parameter of Url object, it is going to update the record
                InitializeComponent();
                _services = new DbService();
                if (obj != null)
                {
                    urlId = obj.Id;
                    TxtUrlName.Text = obj.Name;
                    TxtUrl.Text = obj.Url;
    
    
                    _isUpdate = true;
                }
            }
            private async void btnSaveUpdate_Clicked(object sender, EventArgs e)
            {
                Urls obj = new Urls(); // Use of url object
    
                //Text box value
                obj.Name = TxtUrlName.Text;
                obj.Url = TxtUrl.Text;
    
                // If _isUpdate is true, call UpdateUrls method
                if (_isUpdate)
                {
                    obj.Id = urlId;
                    await _services.UpdateUrls(obj);
                }
                // Else insert record
                else
                {
                    _services.InsertUrls(obj);
                }
                await this.Navigation.PopModalAsync();
            }
    
    
        }
    

    This is AddUrl.xaml

      <ContentPage.Content>
            <StackLayout Margin="10" VerticalOptions="StartAndExpand" HorizontalOptions="FillAndExpand">
                <Entry x:Name="TxtUrlName" Placeholder="Enter Url Name" />
                <Entry x:Name="TxtUrl" Placeholder="Enter Url" />
                <Button x:Name="btnSaveUpdate" Text="Save" Clicked="btnSaveUpdate_Clicked" />
            </StackLayout>
        </ContentPage.Content>
    

    And finally I have a SettingsPage.cs where I have functions to show and add url.

    [XamlCompilation(XamlCompilationOptions.Compile)]
     public partial class SettingsPage : ContentPage
        {
         public Settings Settings { get; set; }
            DbService  services;
            public SettingsPage ()
     {
     InitializeComponent();
                // Creates the Settings Model
         Settings = new Settings();
                // Sets the Settings Model as the BindingContext for "filling" the SettingsPage with the current AppSettings.
         BindingContext = Settings;
                services = new DbService();
    
            }
    
            protected async override void OnAppearing()
            {
                showUrl(); // Returns GetAllUrls
                base.OnAppearing();
            }
    
            private void showUrl()
            {
                var res = services.GetAllUrls();
                lstUrls.ItemsSource = res; // Binding with listview
            }
    
    
            //This method is used to insert data into db 
            private async void BtnAddRecord_Clicked(object sender, EventArgs e)
            {
                await this.Navigation.PushModalAsync(new AddUrl(), true);
    
            }
    
    
    
            // Display alert for update and delete
            private async void lstData_ItemSelected(object sender, SelectedItemChangedEventArgs e)
            {
                if (e.SelectedItem != null)
                {
                    Urls obj = (Urls) e.SelectedItem;
                    string res = await DisplayActionSheet("Operation", "Cancel", null, "Update", "Delete");
    
                    switch (res)
                    {
                        case "Update":
                            await this.Navigation.PushModalAsync(new AddUrl(obj), true);
                            break;
                        case "Delete":
                            services.DeleteUrl(obj);
                            showUrl();
                            break;
    
                    }
    
                    lstUrls.SelectedItem = null;
                }
    
            }
        }
    

    I dont know how to implemet the logic in my code.. I have a CRUD function that works perfectly BUT I need to use it to add items in menu dynamically. Hope someone can show me the way.

    Thanks!


2 additional answers

Sort by: Most helpful
  1. Cole Xia (Shanghai Wicresoft Co,.Ltd.) 6,756 Reputation points
    2021-05-12T03:10:31.587+00:00

    Hello,

    Welcome to Microsoft Q&A!

    We can use FlyoutContentTemplate , it will replace the default flyout content .

    We can simply create a listview and bind list on it ,the list data comes from CRUD functionality .

    Sample code

       <Shell Title="Shell Title" ...>  
         
       <Shell.FlyoutContentTemplate>  
               <DataTemplate>  
                   <StackLayout>  
                       <ListView x:Name="MenuItemsListView"  
                                 SeparatorVisibility="None"  
                                 HasUnevenRows="true"  
                                 ItemsSource="{Binding FlyoutItems}">  
                           <ListView.Header>  
                               <Grid BackgroundColor="#8f0000">  
                                   <Grid.ColumnDefinitions>  
                                       <ColumnDefinition Width="10"/>  
                                       <ColumnDefinition Width="*"/>  
                                       <ColumnDefinition Width="10"/>  
                                   </Grid.ColumnDefinitions>  
                                   <Grid.RowDefinitions>  
                                       <RowDefinition Height="30"/>  
                                       <RowDefinition Height="80"/>  
                                       <RowDefinition Height="Auto"/>  
                                       <RowDefinition Height="10"/>  
                                   </Grid.RowDefinitions>  
                                   <Label Grid.Row="2" Grid.Column="1"  
                                          TextColor="#d7d9b4"  
                                          Text="{Binding Title}"  
                                          FontSize="24"/>  
                               </Grid>  
                           </ListView.Header>  
         
                           <ListView.ItemTemplate>  
                               <DataTemplate>  
                                   <ViewCell>  
                                       <StackLayout Padding="15,10"  
                                                    HorizontalOptions="FillAndExpand">  
                                           <Label VerticalOptions="FillAndExpand"  
                                                  VerticalTextAlignment="Center"  
                                                  Text="{Binding MenuTitle}"  
                                                  TextColor="Black"  
                                                  FontSize="20"/>  
                                       </StackLayout>  
                                   </ViewCell>  
                               </DataTemplate>  
                           </ListView.ItemTemplate>  
                       </ListView>  
                   </StackLayout>  
               </DataTemplate>  
           </Shell.FlyoutContentTemplate>  
    
    
    
       public ObservableCollection<Model> FlyoutItems { get; set; }  
         
       public AppShell()  
       {  
                   FlyoutItems = new ObservableCollection<Model>();  
                   InitializeComponent();  
                   BindingContext = this;  
       }  
         
         
       public void CRUD()    
       {    
           
          var list = conn.Table<Model>().ToListAsync().Result;    
         
          foreach(var item in list)  
          {  
              FlyoutItems.Add(item);  
          }  
       }  
    

    Refer to https://stackoverflow.com/a/66036972/8187800.

    Best Regards,
    Cole Xia


    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

  2. Vikas Madan Surve 1 Reputation point
    2021-09-03T20:51:32.88+00:00

    @Cole Xia (Shanghai Wicresoft Co,.Ltd.) , I am very new to this shell concept, can you please sample for above solutions

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.