locked
Binding a ListView RRS feed

  • Question

  • User249032 posted

    I'm trying to display the images returned from a Bing image search, and there's something not quite right somewhere. I was able to get it working with a single image, but this is my first time using a ListView. As far as I can tell the VM code is working ok - i.e. not getting any error messages - just not seeing anything in the UI. Here's the relevant code...

    VIEW ListView ImageList; ImageList=new ListView{}; ImageList.SetBinding( ListView.ItemsSourceProperty,new Binding("ImageResults",source: vm) ); (ImageList added to UI stack)

    VM private List imageResults; public List ImageResults { get { return _imageResults;} set { if (imageResults != value) { _imageResults=value; PropertyChanged?.Invoke(this,new PropertyChangedEventArgs("ImageResults")); } } }

    ImageResults=(List) client.Images.SearchAsync(query: searchterm).Result.Value;

    thanks, Donald.

    Tuesday, April 9, 2019 1:15 AM

All replies

  • User371688 posted

    Are you achieving this app based on C#?If yes , you should add the listview to the ContentPage;

      Content = ImageList;
    
    Tuesday, April 9, 2019 3:39 AM
  • User249032 posted

    Thanks, but as noted in brackets, I'm adding it to a stack in the UI.

    @jezh said: Are you achieving this app based on C#?If yes , you should add the listview to the ContentPage;

      Content = ImageList;
    
    Tuesday, April 9, 2019 7:23 AM
  • User76049 posted

    Host the Listview in a grid to ensure the StackLayout can fill so the Listview can calculate it's height. Doesn't work as you might expect otherwise. Also you Listview needs a DataTemplate.

    Tuesday, April 9, 2019 7:47 AM
  • User249032 posted

    @NMackay said: Host the Listview in a grid to ensure the StackLayout can fill so the Listview can calculate it's height. Doesn't work as you might expect otherwise. Also you Listview needs a DataTemplate.

    Well, having not used it before, I wasn't sure what to expect, :-) I only know it's not working yet (as usual, the doco/blogs on this topic don't cover what I'm trying to achieve - present all returned images so that the user can select from them - so I'm trying to put the pieces together as to how to make it work for my scenario). I'll check out those things you mentioned and let you know how I go. Thanks!

    Tuesday, April 9, 2019 7:55 AM
  • User76049 posted

    The docs are quite useful.

    https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/listview/customizing-cell-appearance

    Tuesday, April 9, 2019 8:03 AM
  • User249032 posted

    @NMackay said: The docs are quite useful.

    https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/listview/customizing-cell-appearance

    Well, maybe that's an issue with an ambiguous title. It says "Customizing ListView Cell Appearance", and since I don't want to do any "customizing" yet - juts get the basic view working first - I hadn't looked at that. If this is necessary for it to work to begin with, then perhaps "initializing" or similar might be a better wording (though that's not your issue). I think now this may be why it's not working, so thanks for pointing that out! :-)

    Tuesday, April 9, 2019 8:10 AM
  • User249032 posted

    So I've added some code for a DataTemplate to the best of my understanding of how it works from the MS DataTemplate doco (having never used one before), but still nothing coming through on the UI. Not sure what I'm missing here (or if I need both SetBinding statements)...? Here's all my code from the UI...

    ListView ImageList; var pictureTemplate=new DataTemplate(()=>{ var grid=new Grid(); var picture=new Image(); picture.SetBinding(Image.SourceProperty,new Binding("ImageResults",source:vm)); grid.Children.Add(picture); return new ViewCell{ View=grid}; }); ImageList=new ListView{ItemTemplate=pictureTemplate}; ImageList.SetBinding( ListView.ItemsSourceProperty,new Binding("ImageResults",source: vm) );

    Wednesday, April 10, 2019 4:12 AM
  • User371688 posted

    I couldn't test your code since I don't have the whole code,but you can try to define the ColumnDefinitions property, for example(define 2 columns):

     var grid=new Grid();
      grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(0.5, GridUnitType.Star) });
      grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(0.5, GridUnitType.Star) });
    

    Besides, where is your source data? and I couldn't understand why the the rest of the following two line codes is the same.

    // here you should bind the value of the  Object Model (e.g. ImageObject)
     picture.SetBinding(Image.SourceProperty,new Binding("ImageResults",source:vm));
    

    and

     ImageList.SetBinding( ListView.ItemsSourceProperty,new Binding("ImageResults",source: vm) );
    

    You can also binding the data source like this

    ImageList=new ListView{ItemsSource = myImageResults, ItemTemplate=pictureTemplate};
    

    Note: Let's say the data source is as follows :

     pulic ObservableCollection<ImageObject>  myImageResults  = new ObservableCollection<ImageObject>();
    

    Note: you can refer to the following document and it contains a sample you can check: https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/templates/data-templates/creating

    please check class WithDataTemplatePageCS.cs https://github.com/xamarin/xamarin-forms-samples/blob/master/Templates/DataTemplates/DataTemplates/CS/WithDataTemplatePageCS.cs

    Wednesday, April 10, 2019 10:15 PM
  • User249032 posted

    @jezh said: I couldn't test your code since I don't have the whole code,but you can try to define the ColumnDefinitions property, for example(define 2 columns):

     var grid=new Grid();
      grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(0.5, GridUnitType.Star) });
      grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(0.5, GridUnitType.Star) });
    

    That didn't change anything. :-(

    Besides, where is your source data?

    I'm doing a Bing image search and assigning the results to ImageResults in my vm, which has been cast to a List. I'll include the full list of relevant code at the end (I know the data is ok, because I was able to successfully bind a single image - just can't get it working for the full set of images).

    and I couldn't understand why the the rest of the following two line codes is the same.

    // here you should bind the value of the  Object Model (e.g. ImageObject)
     picture.SetBinding(Image.SourceProperty,new Binding("ImageResults",source:vm));
    

    and

     ImageList.SetBinding( ListView.ItemsSourceProperty,new Binding("ImageResults",source: vm) );
    

    Because I don't know how to bind a ListView and I'm trying different things to get it to work. Do you bind to the list itself, or to the objects within? (I also tried both of those individually, also didn't work) I'm not sure what you mean by bind the value of the object model?

    You can also binding the data source like this

    ImageList=new ListView{ItemsSource = myImageResults, ItemTemplate=pictureTemplate};
    

    I tried ImageList=new ListView{ItemTemplate=pictureTemplate,ItemsSource=vm.ImageResults}; but that also didn't work.

    Note: Let's say the data source is as follows :

     pulic ObservableCollection<ImageObject>  myImageResults  = new ObservableCollection<ImageObject>();
    

    When I try to cast to ObservableCollection I get "Unable to cast object of type 'System.Collections.Generic.List1[Microsoft.Azure.CognitiveServices.Search.ImageSearch.Models.ImageObject]' to type 'System.Collections.ObjectModel.ObservableCollection1[Microsoft.Azure.CognitiveServices.Search.ImageSearch.Models.ImageObject]'.", whereas the vm code seems to be happy when it's cast to a List (builds and runs with no exceptions or other issues).

    Here's all the code as it stands right now (except my API key of course :-) )...

    MAINPAGE StackLayout MainStack ListView ImageList; Viewmodel vm; Grid MainGrid=new Grid(); vm=new Viewmodel(); var pictureTemplate=new DataTemplate(()=>{ var grid=new Grid(); grid.ColumnDefinitions.Add(new ColumnDefinition{ Width=new GridLength(0.5,GridUnitType.Star)}); grid.ColumnDefinitions.Add(new ColumnDefinition{ Width=new GridLength(0.5,GridUnitType.Star)}); var picture=new Image(); picture.SetBinding(Image.SourceProperty,new Binding("ImageResults",source:vm)); grid.Children.Add(picture); return new ViewCell{ View=grid}; }); ImageList=new ListView{ ItemTemplate=pictureTemplate // ,ItemsSource=vm.ImageResults }; //ImageList.SetBinding( ListView.ItemsSourceProperty,new Binding("ImageResults",source: vm) ); MainStack=new StackLayout{VerticalOptions=LayoutOptions.Center}; MainGrid.Children.Add(MainStack); MainStack.Children.Add(ImageList); Content=MainGrid;

    VIEWMODEL private List imageResults; public List ImageResults { get { return _imageResults;} set { if (imageResults != value) { _imageResults=value; PropertyChanged?.Invoke(this,new PropertyChangedEventArgs("ImageResults")); } } }

    string searchterm=800897143558; using(var client=new ImageSearchClient(new ApiKeyServiceClientCredentials(AzureKey))){ client.Endpoint="https://australiaeast.api.cognitive.microsoft.com/"; ImageResults=(List) client.Images.SearchAsync(query: searchterm).Result.Value; }

    Friday, April 12, 2019 12:51 AM
  • User249032 posted

    I think I may be onto why this isn't working - an annoying red herring. Please see https://forums.xamarin.com/discussion/155770/images-from-a-variable-not-loading-displaying/p1?new=1

    Friday, April 26, 2019 7:34 AM