locked
List model Items in a categorized list in view xamarin RRS feed

  • Question

  • User333528 posted

    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

    Saturday, June 23, 2018 6:38 AM

Answers

  • User364855 posted

    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???

    You could add a string in ResturentPair class.

    public class ResturentPair
    {
        public string Category { get; set; }
        public Resturent Item1 { get; set; }
        public Resturent Item2 { get; set; }
    }
    

    And in GetDishItems()

        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 { Category = list[i].Category, Item1 = list[i], Item2 = list[i+1] });
            }
            return res;
        }
    

    Do you want something like that?

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Tuesday, June 26, 2018 8:15 AM

All replies

  • User333528 posted

    with regard to the above question this is the output i am getting from the server { "Resturent": [ { "ID": "12238000003927", "Category": "LEAF TEAPRE", "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 TEAPRE", "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 BAGSPRE", "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 BAGSPRE", "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 TEAGOU", "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 BAGSGOU", "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": "" } ] }

    Saturday, June 23, 2018 7:24 PM
  • User364855 posted

    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.

    Tuesday, June 26, 2018 7:10 AM
  • User333528 posted

    @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 :-(

    Tuesday, June 26, 2018 8:01 AM
  • User364855 posted

    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???

    You could add a string in ResturentPair class.

    public class ResturentPair
    {
        public string Category { get; set; }
        public Resturent Item1 { get; set; }
        public Resturent Item2 { get; set; }
    }
    

    And in GetDishItems()

        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 { Category = list[i].Category, Item1 = list[i], Item2 = list[i+1] });
            }
            return res;
        }
    

    Do you want something like that?

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Tuesday, June 26, 2018 8:15 AM
  • User333528 posted

    @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 ????

    Tuesday, June 26, 2018 9:16 AM
  • User333528 posted

    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>
    
    Tuesday, June 26, 2018 9:24 AM
  • User333528 posted

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

    Tuesday, June 26, 2018 11:04 AM
  • User333528 posted

    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

    Wednesday, June 27, 2018 6:39 PM