简体   繁体   中英

Xamarin.Forms Help loading Images from Url/Uri directly from viewmodel

Im currently working on a cross-platform App (iOS & Android) on Xamarin.Forms My current goal is to develop a slider with images for multiple services.

Something like:

IMAGE | IMAGE | IMAGE | IMAGE

label | label | label | label

scrollable to the sides.

For this I created:

-The Services class

string ID
string Name
string ServiceType
ImageSource ImgUrl 

-A ViewModel (HLandingVM) Here I prepare the lists objects and load them into the page

-HLandingPage.xaml for the view

-HLandingPage.cs to load the viewmodel

The main issue is that I do see my labels correctly displayed and scrolling as they are supposed to. But the images are not displaying at all.

Ive tryed passing to the model: An ImageSource , Image by itself, passing just an Uri for the Binding. But the Image will not display at all.

-Class

 `private string id;
    public string Id
    {
        get { return id; }
        set
        {
            id = value;
            OnPropertyChange("Id");
        }
    }

    private string name;
    public string Name
    {
        get { return name; }
        set
        {
            name = value;
            OnPropertyChange("Name");
        }
    }

    private string servicetype;
    public string ServiceType
    {
        get { return servicetype; }
        set
        {
            servicetype = value;
            OnPropertyChange("ServiceType");
        }
    }



    private ImageSource imgUrl;
    public ImageSource ImgUrl 
    {
        get { return imgUrl; }
        set
        {
            imgUrl = value;
            OnPropertyChange("ImgUrl");
        }
    }`

-VIEW

`

<StackLayout Margin="10,0,5,0" WidthRequest="150" HeightRequest="150">
   <Image HorizontalOptions="Start"  WidthRequest="150" HeightRequest="150" >
              <Image.Source>
                  <UriImageSource Uri="{Binding ImgUrl}" />
              </Image.Source>
   </Image>
    <Label Style="{StaticResource BoldLabel}" HorizontalTextAlignment="Center" FontSize="13" LineBreakMode="TailTruncation" Text="{Binding Name}" TextColor="Black"/>
</StackLayout>

`

-VM

Adding Services and ImageSources `

Services.Add(
new Services
{
Name = "Service1",
ServiceType = "Owner",
ImgUrl = new UriImageSource()
{
Uri= new Uri("https://via.placeholder.com/150 "),
CachingEnabled = false
}
});
Services.Add(
new Services
{
Name = "Service2",
ServiceType = "Owner",
ImgUrl = new UriImageSource()
{
Uri = new Uri("https://via.placeholder.com/100 "),
CachingEnabled = false
}
});
Services.Add(
new Services
{
Name = "Service3",
ServiceType = "Owner",
ImgUrl = new UriImageSource()
{
Uri = new Uri("https://via.placeholder.com/250 "),
CachingEnabled = false
}
}); 

`

-Trying (not working) to load a Resource Image if the URI returns empty

`

foreach (var service in List)
                {
                    if (service.ImgUrl.IsEmpty)
                    {
                        var assembly = typeof(HLandingPage);
                        service.ImgUrl = ImageSource.FromResource("App.Images.150.png", assembly);
                    }
                    OwnerServices.Add(service);

`

No aparent erros triggered. Just empty pictures.

first, you can simplify your Image

<Image HorizontalOptions="Start"  WidthRequest="150" HeightRequest="150" Source="{Binding ImgUrl}" />

second, make your ImgUrl property a string

Services.Add(
  new Services
  {
    Name = "Service1",
    ServiceType = "Owner",
    ImgUrl = "https://via.placeholder.com/150"
  });

finally, be sure you're not actually including a trailing space in your url

Generally, we usually define the imgUrl as a string type ,just as follows

private string imgUrl;
public string ImgUrl 
{
    get { return imgUrl; }
    set
    {
        imgUrl = value;
        OnPropertyChange("ImgUrl");
    }
}

And binding like this:

<Image Source="{Binding ImgUrl}" />

Of course, when you init the value of ImgUrl . it should be also be string type.

And there is a sample to display image from internet, you can refer to it. https://github.com/xamarin/xamarin-forms-samples/tree/master/GetStarted/Tutorials/ListViewTutorial

Thank you guys for your help!

Indeed a string for the image did the trick for the souce binding.

Another detail I was missing that I noticed was setting the ItemsSource in the xaml.cs

 protected override void OnAppearing()
        {
            base.OnAppearing();
            viewModel.UpdateServices();
            OwnerServicesSlider.ItemsSource = viewModel.OwnerServices;
        }

After this Image started showing on the first Item

   private string imgUrl;
        public string ImgUrl
        {
            get { return imgUrl; }
            set
            {
                imgUrl = value;
                OnPropertyChange("ImgUrl");
            }
        }

I also added the ItemSource to the xaml

<controls:HorizontalScrollView HeightRequest="200" 
                                   SelectedCommand="{Binding OpenPageCommand}"
                                   Orientation="Horizontal"  
                                   ItemsSource="{Binding OwnerServices}"
                                   x:Name="OwnerServicesSlider">
                <controls:HorizontalScrollView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <StackLayout Margin="10,0,5,0" WidthRequest="150" HeightRequest="150">
                                <Image HorizontalOptions="Start"  Source="{Binding ImgUrl}" WidthRequest="150" HeightRequest="150"/>
                                <Label Style="{StaticResource BoldLabel}" HorizontalTextAlignment="Center" FontSize="13" LineBreakMode="TailTruncation" Text="{Binding Name}" TextColor="Black"/>
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </controls:HorizontalScrollView.ItemTemplate>
            </controls:HorizontalScrollView>

And Im filling my list with different links

 Services.Add(
               new Services
               {
                   Name = "Service1",
                   ServiceType = "Owner",
                   ImgUrl = "http://lorempixel.com/150/150"

               });
            Services.Add(
                new Services
                {
                    Name = "Service2",
                    ServiceType = "Owner",
                    ImgUrl = "https://via.placeholder.com/150"

                }); ;
            Services.Add(
               new Services
               {
                   Name = "Service3",
                   ServiceType = "Owner",
                   ImgUrl = "https://www.stevensegallery.com/150/150"


               });

The Image from https://via.placeholder.com/150 always show but the other two are not showing with the Binding. Is there somethign Im missing?

I tryed moving the image in the list to be second or even third but only the placeholder shows in any of the positions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM