List model Items in a categorized list in view xamarin

with a Resturent model as below i am retrieving the data to appear in list view as lists with two colomns

the model

    public class ResturentItems
        {
            [JsonProperty("Resturent")]
            public List<Resturent> Resturent { get; set; }
        }

        public class Resturent : ModelBase
        {
            [JsonIgnore]
            private static readonly ILocalFileToBase64StringConverter _base64Converter = DependencyService.Get<ILocalFileToBase64StringConverter>();

            [JsonProperty("ID")]
            public string ID { get; set; }

            [JsonProperty("Category")]
            public string Category { get; set; }

            [JsonProperty("Name")]
            public string Name { get; set; }

            [JsonProperty("Code")]
            public string Code { get; set; }

            [JsonProperty("Description")]
            public string Description { get; set; }

            [JsonProperty("Price")]
            public string Price { get; set; }

            [JsonProperty("isservicecharge")]
            public bool isservicecharge { get; set; }

            [JsonProperty("isaddonapplicable")]
            public bool isaddonapplicable { get; set; }

            [JsonProperty("CostPrice")]
            public string CostPrice { get; set; }

            [JsonProperty("Date")]
            public string Date { get; set; }

            [JsonProperty("Image")]
            public string Image { get; set; }

            [JsonIgnore]
            public ImageSource ImageSource => string.IsNullOrEmpty(Image) ? "userpic.jpg" : ImageSource.FromStream(() => new MemoryStream(_base64Converter.ConvertBack(Image)));

        }

and the data retrieve by the below code

private List<ResturentPair> GetDishItems(List<Resturent> list)
        {         

            var res = new List<ResturentPair>();
            for (int i = 0; i < list.Count-1; i += 2)
            {
                res.Add(new ResturentPair { Item1 = list[i], Item2 = list[i+1] });
            }
            return res;
        }   

for your convenience i will show below the model as well

public class ResturentPair
    {
        public Resturent Item1 { get; set; }

        public Resturent Item2 { get; set; }
    }

the full code below on the viewmodel

public class RootViewModel : ContextViewModelBase
    {
        private readonly IRestService _restService;
        private RootPage _page;

        public RootViewModel(IAppContext context, IRestService restService, IStatusBarService statusBarService) : base(context)
        {
            _restService = restService;
            statusBarService.ShowStatusBar();
            statusBarService.SetDefaultFontColor();
            ActionCommand = new Command(OnActionCommand);
            PageAppearingCommand = new Command<RootPage>(OnPageAppearingCommand);
            PageDisappearingCommand = new Command(OnPageDisappearingCommand);
        }

        public List<ResturentPair> Items { get; set; }

        public List<Resturent> CarouselItems { get; set; }

        public string Photo { get; set; } = "Photo.png";

        public bool IsLoading { get; set; } = true;

        public ICommand ActionCommand { get; }

        public string PagingText { get; set; }

        private async void OnPageAppearingCommand(RootPage page)
        {
            _page = page;
            Photo = $"{DefaultValues.ServerUrl}{Context.User.PhotoUrl}";
            IsLoading = true;
            var items = await _restService.GetFoodMenuInfo();
            CarouselItems = GetCarouselItems(items.Resturent);
            Items = GetDishItems(items.Resturent);
            OnCarouselViewItemSelected(this, new SelectedItemChangedEventArgs(CarouselItems.First())); // we call it for setting paging
            IsLoading = false;
            _page.CarouselView.ItemSelected += OnCarouselViewItemSelected;
        }

        private void OnPageDisappearingCommand()
        {
            _page.CarouselView.ItemSelected -= OnCarouselViewItemSelected;
        }

        private List<Resturent> GetCarouselItems(List<Resturent> items)
        {         

            var carouselViewItems = new List<Resturent>();
            // put your logic here for selecting items for carouselView
            for (var i = 0; i < 4; i++)
            {
                carouselViewItems.Add(items[i]);
            }
            return carouselViewItems;
        }       

        private List<ResturentPair> GetDishItems(List<Resturent> list)
        {         

            var res = new List<ResturentPair>();
            for (int i = 0; i < list.Count-1; i += 2)
            {
                res.Add(new ResturentPair { Item1 = list[i], Item2 = list[i+1] });
            }
            return res;
        }


        private void OnCarouselViewItemSelected(object sender, SelectedItemChangedEventArgs e)
        {
            var selectedIndex = CarouselItems.IndexOf(e.SelectedItem as Resturent);
            var pagingResult = string.Empty;
            for (var i = 0; i < CarouselItems.Count; i++)
            {
                if (i == selectedIndex)
                {
                    pagingResult += $" \uf26d ";
                }
                else
                {
                    pagingResult += $" \uf26c ";
                }
            }
            PagingText = pagingResult;
        }

        private void OnActionCommand()
        {
            Navigator.PushAsync<SettingsViewModel>();
        }
    }

so finally the Restaurant details appear with all the details with name and the category , ETC, but my requirement i only want to show the categories ( the Restaurant items list need to be listed as categories, so any idea how to retrieve only to list by only categories of the restaurant items ?? thank you advance for your support

Best Answer

Answers

  • PandukaWeerasekaraPandukaWeerasekara USMember ✭✭

    with regard to the above question this is the output i am getting from the server
    {
    "Resturent": [
    {
    "ID": "12238000003927",
    "Category": "LEAF TEA_PRE",
    "Name": "LT 100G COP",
    "Code": "80067-012",
    "Description": "LT 100G COP",
    "Price": "140.000",
    "isservicecharge": 0,
    "isaddonapplicable": 0,
    "CostPrice": ".000",
    "Date": "12228000000000",
    "Image": ""
    },
    {
    "ID": "12238000004015",
    "Category": "LEAF TEA_PRE",
    "Name": "LEAF TEA 200g PREMIUM",
    "Code": "80033-024",
    "Description": "LEAF TEA 200g\/24 PREMIUM (PILLOW PACK)",
    "Price": "310.000",
    "isservicecharge": 0,
    "isaddonapplicable": 0,
    "CostPrice": ".000",
    "Date": "12228000000000",
    "Image": ""
    },
    {
    "ID": "12238000006325",
    "Category": "TEA BAGS_PRE",
    "Name": "PREMIUM TAG TBAG 050 ",
    "Code": "80021-024",
    "Description": "TAG TBAG 050\/2.0g\/24 PREMIUM",
    "Price": "240.000",
    "isservicecharge": 0,
    "isaddonapplicable": 0,
    "CostPrice": ".000",
    "Date": "12228000000000",
    "Image": ""
    },
    {
    "ID": "12238000006192",
    "Category": "TEA BAGS_PRE",
    "Name": "TAG TBAG 025 PREMIUM",
    "Code": "80011-012",
    "Description": "TAG TBAG 025\/2.0g\/12 PREMIUM",
    "Price": "125.000",
    "isservicecharge": 0,
    "isaddonapplicable": 0,
    "CostPrice": ".000",
    "Date": "12228000000000",
    "Image": ""
    },
    {
    "ID": "12238000006703",
    "Category": "LEAF TEA_GOU",
    "Name": "TINCADDY 125g EA",
    "Code": "81032-006",
    "Description": "TIN CADDY 125g\/06 ENGLISH AFTERNOON",
    "Price": "450.000",
    "isservicecharge": 0,
    "isaddonapplicable": 0,
    "CostPrice": ".000",
    "Date": "12228000000001",
    "Image": ""
    },
    {
    "ID": "12238000003727",
    "Category": "TEA BAGS_GOU",
    "Name": "FOIL ENV TBAG 025 ENG BFST",
    "Code": "80086-012",
    "Description": "FOIL ENV TBAG 025\/2.0g\/12 ENGLISH BREAKFAST",
    "Price": "160.000",
    "isservicecharge": 0,
    "isaddonapplicable": 0,
    "CostPrice": ".000",
    "Date": "12228000000001",
    "Image": ""
    }
    ]
    }

  • BillyLiuBillyLiu Member, Xamarin Team Xamurai

    Do you want to get the Category from each list item? Or do you want to only get Category from the server?
    If it is the first case, you could create a list for Category, and get Category form items by something like item[i].Category
    For example:

            private async void OnPageAppearingCommand(RootPage page)
            {
               ///...
                var items = await _restService.GetFoodMenuInfo();
                List<string> list = new List<string>();
                foreach(var item in items)
                {
                    if (!list.Contains(item.Category))
                    {
                        list.Add(item);
                    }
                }
                ///...
            }
    

    If you only want to get Category form the server, you need to modify your webservice.

  • PandukaWeerasekaraPandukaWeerasekara USMember ✭✭

    @BillyLiu Thank you so much for your help and support really appreciate it, as you said yes i need to get the Category from each list item, so the issue hear is that i create the list of items in a way that shows as item1 and item2 ( as you can see mentioned above "ResturentPair" class.) so i am bit confused with how to show the categories in that RestutrentPair???

    Note:- by the way my final ultimate goal is to create ,when user tap on the category item on the root page, that page will navigate to individual items page corresponds to the respective categories, but still dont know how to do it :-(

  • PandukaWeerasekaraPandukaWeerasekara USMember ✭✭

    @BillyLiu thanks for the reply , after i insert your code i am getting categories with repeating the same category ( as you can see the red circles in the image attached) because the expectation to category be distinct ( only one category to be appear on each cell only once) , also as you can see the two columns repeating items rather than arranging one by one , (by the way two columns are the items1 and items2 in the model) have any idea how to solve the issue
    ????

  • PandukaWeerasekaraPandukaWeerasekara USMember ✭✭

    for your convenience this is the template that i am showing the item1 and item2 template in xaml

    <Grid xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
         xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms" 
         x:Class="FormsApplication.Templates.DashboardCardTemplate" 
         ColumnSpacing="8" RowSpacing="0" 
         HeightRequest="160" Padding="8,0,8,8">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid Grid.Column="0">
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <ffimageloading:CachedImage Grid.RowSpan="2" Source="{Binding Item1.ImageSource}" Aspect="AspectFill" DownsampleToViewSize="true"/>
            <BoxView Color="Black" Opacity="0.5" Grid.RowSpan="2" />
            <Label Grid.Row="0" Text="{Binding Item1.Name}" VerticalOptions="End" TextColor="White" FontSize="15" Margin="16,0" />
            <Label Grid.Row="1" Text="{Binding Item1.Category}" VerticalOptions="End" TextColor="White" FontSize="10" Margin="16,0,16,8" Opacity="0.75"
                LineBreakMode="TailTruncation"/>
            <Grid.GestureRecognizers>
                <TapGestureRecognizer Command="{Binding Item1.ClickCommand}" CommandParameter="{Binding Item1.Instance}" />
            </Grid.GestureRecognizers>
        </Grid>
        <Grid Grid.Column="1">
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <ffimageloading:CachedImage Grid.RowSpan="2" Source="{Binding Item2.ImageSource}" Aspect="AspectFill" />
            <BoxView Color="Black" Opacity="0.5" Grid.RowSpan="2" />
            <Label Grid.Row="0" Text="{Binding Item2.Name}" VerticalOptions="End" TextColor="White" FontSize="15" Margin="16,0" />
            <Label Grid.Row="1" Text="{Binding Item2.Category}" VerticalOptions="End" TextColor="White" FontSize="10" Margin="16,0,16,8" Opacity="0.75" />
            <Grid.GestureRecognizers>
                <TapGestureRecognizer Command="{Binding Item2.ClickCommand}" CommandParameter="{Binding Item2.Instance}" />
            </Grid.GestureRecognizers>
        </Grid>
    </Grid>
    
  • PandukaWeerasekaraPandukaWeerasekara USMember ✭✭

    @BillyLiu any idea to make this work??? , thanks for your help so far.

  • PandukaWeerasekaraPandukaWeerasekara USMember ✭✭

    Thank for your support , no need of struggle with xamarin code for filtering category by code , i used php to filer and retrieve for the server it self, this is the one of the reasons i didn't want to bother with C# code in xamarin because it takes long time to discover and i have to wait until some one answer the question. because some time xamarin dosen't have specific codes when we need to customize , like the scenario i have, very disappointing with xamarin

Sign In or Register to comment.