Search code examples
.netimagereleasemauicollectionview

CollectionView item not appearing in release mode


zIn .net Maui application I have the following problem: my collection view worked fine in debug mode, but in release mode instead of an image and two labels, the collection view shows only a white rectangle. The onClick function worked properly: This is xaml:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:vm="clr-namespace:VegaMaui"
             xmlns:model="clr-namespace:VegaMaui.Model"
             x:Class="VegaMaui.MenuDetails"   x:DataType="vm:MenuDetailsViewModel"        
             Title="Ապրանքներ"
             BackgroundColor="#f9f9f9">   
    <CollectionView 
            RemainingItemsThreshold="5"
            RemainingItemsThresholdReachedCommand="{Binding LoadMoreS}"
            SelectionMode="Single"
            SelectionChanged="OnProdSelectionChanged"
            ItemsSource="{Binding ProdListS}"
            x:Name="prodcollect">
        <CollectionView.ItemsLayout>
            <GridItemsLayout Orientation="Vertical"
                        Span="2" />
        </CollectionView.ItemsLayout>       
        <CollectionView.ItemTemplate>            
            <DataTemplate x:DataType="model:ProductImg">                    
                <Grid Margin="5,5,5,5" Padding="1" >
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />                           
                    </Grid.ColumnDefinitions>
                    <Image
                        Grid.Row="0"                           
                        Grid.Column="0"                         
                        Source= "{Binding firstPicture}"                        
                        Aspect="AspectFill"/>                    
                    <Label Grid.Row="1"
                        Grid.Column="0"                      
                        FontAttributes="Bold"
                        BackgroundColor="White"
                        LineBreakMode="WordWrap"
                        Text="{Binding product_Name}"
                        VerticalOptions="Start" />
                    <Label Grid.Row="2"
                        Grid.Column="0"                      
                        FontAttributes="Bold"
                        LineBreakMode="WordWrap"
                        BackgroundColor="White"
                        Text="{Binding product_DisPrice, StringFormat='{0:F0} դր.'}"
                        TextColor ="Red" FontSize="Default"
                        VerticalOptions="Start" />
                    <Label Grid.Row="3"
                        Grid.Column="0"                                   
                        LineBreakMode="WordWrap"
                        BackgroundColor="White"
                        IsVisible="{Binding IsShowMode}"
                        Text="{Binding product_Price, StringFormat='{0:F0} դր.'}"
                        TextColor="#40414a"  FontSize="Default" 
                        TextDecorations="Strikethrough"
                        VerticalOptions="Start" />

                </Grid>                    
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>   
</ContentPage>

This is ViewModel:

namespace VegaMaui
{
    public  class MenuDetailsViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private int startindex = 1;
        private int endindex = 10;        
        private string SubGrInd = "";
        private readonly VegaApi ApiControl;
        private void OnPropertyChanged(string propertyName) =>
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        public MenuDetailsViewModel(string SubGroup)
        {
            SubGrInd = SubGroup;    
             ApiControl = new();
            // Task.Run(() => this.LoadData(SubGroup)).Wait();
            ProdListS = new ObservableCollection<Model.Product>();
            new Thread(() =>
            {
                LoadDataS();
            }).Start();
            
        }        
        public async Task LoadDataS()
        {           
            var data =  await ApiControl.GetMenuDetAsync(SubGrInd, startindex,endindex);
            ProdListS = new ObservableCollection<Model.Product>(data);
            PropertyChanged.Invoke(this,new PropertyChangedEventArgs(nameof(ProdListS)));
        }
        public ICommand LoadMoreS => new Command(async () =>
        {           
            startindex += 16;
            endindex += 16;
                ObservableCollection<Model.Product> data = null;
                new Thread(() =>
                {
                     data=  ApiControl.GetMenuDetAsync(SubGrInd, startindex, endindex).Result;          
                    foreach (var item in data)
                    {
                        ProdListS.Add(item);
                        PropertyChanged.Invoke(this, new PropertyChangedEventArgs(nameof(ProdListS)));
                    }               
                }).Start();            
        });       
        public ObservableCollection<Model.Product> ProdListS { get; set; } 
    }
}
    }        
    public async Task LoadDataS()
    {           
        var data =  await ApiControl.GetMenuDetAsync(SubGrInd, startindex,endindex);
        ProdListS = new ObservableCollection<Model.Product>(data);
        PropertyChanged.Invoke(this,new PropertyChangedEventArgs(nameof(ProdListS)));
    }
    public ICommand LoadMoreS => new Command(async () =>
    {           
        startindex += 16;
        endindex += 16;
            ObservableCollection<Model.Product> data = null;
            new Thread(() =>
            {
                 data=  ApiControl.GetMenuDetAsync(SubGrInd, startindex, endindex).Result;          
                foreach (var item in data)
                {
                    ProdListS.Add(item);
                    PropertyChanged.Invoke(this, new PropertyChangedEventArgs(nameof(ProdListS)));
                }               
            }).Start();            
    });       
    public ObservableCollection<Model.Product> ProdListS { get; set; } 
}

}

public partial class MenuDetails : ContentPage { public string[] ImgList;

private MenuDetailsViewModel _mdvm;
public MenuDetails(string subGID)
{        
    BindingContext = _mdvm = new MenuDetailsViewModel(subGID);
    InitializeComponent();    
   
}
async void OnProdSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    
    Model.Product prodItem = this.prodcollect.SelectedItem as Model.Product;
    int id_Param = prodItem.product_Id;
    VegaApi ApiControl = new();
    List<Model.ProdParams> ParamList = await ApiControl.GetParamDetAsync(id_Param.ToString());      
    ProdInformation ProfilePage = new ProdInformation();
    ProfilePage.Title = this.Title;
    ProfilePage.BindingContext = prodItem;        
    VerticalStackLayout PropsStack = ProfilePage.FindByName<VerticalStackLayout>("InfoLayout");
    //Label NmLabel = ProfilePage.FindByName<Label>("prodname");
    //NmLabel.Text = prodItem.product_Name;
    //Label PrLabel = ProfilePage.FindByName<Label>("prodprice");
    //PrLabel.Text = prodItem․+ " դր.";
   
    // Adding Images carousel view      
    string[] picarray = prodItem.product_PicturePath.Split('@');
        System.Collections.ObjectModel.ObservableCollection<Promo> Data = new System.Collections.ObjectModel.ObservableCollection<Promo>();      
    Data.Add(new Promo() { ImgSource =prodItem.firstPicture});
    if (picarray.Count() > 1)
    {          
        for (int k = 1; k < picarray.Count(); k++)
        {
            if (picarray[k] != null && picarray[k].Length > 3)
            {
                Data.Add(new Promo() { ImgSource = "https://vega.am/image/"+ picarray[k] });
            }
        }
    }
   
   CarouselView CurCarousel= ProfilePage.FindByName<CarouselView>("pcarousel");
    CurCarousel.ItemsSource = Data;
    //  StackLayout slayout = new StackLayout();    
   
   
   // PropsStack.Add(primage);
    List<int> TitleIds = (from el in ParamList select el.Title_Id).Distinct().ToList();
    if (TitleIds != null && TitleIds.Count > 0)
    {
        for (int j = 0; j<TitleIds.Count; j++)
        {
            List<Model.ProdParams> subLst= ParamList.Where(p => p.Title_Id == TitleIds[j]).ToList();
            if(subLst != null && subLst.Count > 0)
            {
                Label ltitle= new Label();
                ltitle.Text = subLst[0].Title_Name;
                ltitle.FontSize = 18;
                ltitle.TextColor = Color.FromRgb(16, 26, 175);
                ltitle.Padding = new Thickness(3, 5, 3, 5);
                ltitle.HorizontalOptions = LayoutOptions.Start;
                PropsStack.Add(ltitle);
                Grid CurGrid = new Grid
                {
                    
                    ColumnDefinitions =
                     {
                        new ColumnDefinition{Width = new GridLength(5, GridUnitType.Star)},
                        new ColumnDefinition{Width = new GridLength(3, GridUnitType.Star)}
                     }
                };                    
                for (int q=0;q< subLst.Count;q++)
                {     
                    CurGrid.AddRowDefinition(new RowDefinition());
                   
                    
                    CurGrid.Add(new Label
                    {
                        
                        Text = subLst[q].Param_Name+" ",
                        LineBreakMode = LineBreakMode.WordWrap,
                        MaxLines =2,
                        HorizontalOptions = LayoutOptions.Start,
                        VerticalOptions = LayoutOptions.Center
                    },0,q);
                    CurGrid.Add(new Label
                     {
                        Text = subLst[q].Param_Value,
                        LineBreakMode = LineBreakMode.WordWrap,
                        MaxLines = 2,
                        HorizontalOptions = LayoutOptions.Start,
                        VerticalOptions = LayoutOptions.Center
                    },1,q);
                }
                PropsStack.Add(CurGrid);
            }
        }
    }        
    await Navigation.PushAsync(ProfilePage);
}

}


Solution

  • I see bound ItemsSource:

    ItemsSource="{Binding ProdListS}"
    

    Specified ProductImg model:

    <DataTemplate x:DataType="model:ProductImg">
    

    And yet in code you have:

    public ObservableCollection<Model.Product> ProdListS { get; set; } 
    

    This is what you should work on.

    It is perfectly fine to mismatch models, even do not specify one as DataType of your DataTemplate. As long as you debug.

    In release things are not the same.