locked
Entry Completed trigger Listview Refresh - MVVM RRS feed

  • Question

  • User339328 posted

    Hi,

    I have a Xam Forms App containing an Entry and a Listview.

    I've tried to implement the MVVM design but somethings still puzzle me.

    From what I understand, I will do the binding in the View(XAML) for the Listview datasource and data template. However, I need the search terms to come from the Entry on Complete event, which will trigger a weather service to retrieve an ObservableCollection to be updated into the listview binding.

    Currently, I'm doing it like this in the XAML Code Behind:

        ObservableCollection<WeatherResultModel> resultList; 
    private async void Entry_Completed(object sender, EventArgs e)
        {
            string input = ((Entry)sender).Text;
            if (input != null)
            {
                WeatherService weatherService = new WeatherService();
                resultList = await weatherService.GetForecastByCityOrCountry(input);
    
                SearchResultListView.ItemsSource = resultList;
            }
        }
    

    How can I do this in a way that fits the MVVM paradigm?

    Thanks!

    Friday, August 18, 2017 2:34 PM

Answers

  • User192947 posted

    Hello @Zedex ,

    Why you dont use the Search bar? For example if your model is :

     public class WeatherResultModel
                {
                    public string ResultValue { get; set; }
                }
    

    and your collection is :

    public class WeatherResultCollection
            {
                public ObservableCollection<WeatherResultModel> Items { get; set; }
                public WeatherResultCollection()
                {
                    Items = new ObservableCollection<WeatherResultModel>()
                    {
                        new WeatherResultModel() {ResultValue = "Default value"}
                    };
                }
            }
    

    Your View will be like :

    <StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand">
                    <SearchBar Placeholder="Search..." TextChanged="SearchBar_TextChanged"/>
                    <ListView x:Name="SearchResultListView" VerticalOptions="FillAndExpand"
                              IsPullToRefreshEnabled="True">
                        <ListView.ItemTemplate>
                            <DataTemplate>
                                <ViewCell>
                                    <StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand">
                                        <Label Text="{Binding ResultValue}"  TextColor="Black" Font="Bold,14"/>
                                        <!-- ... -->
                                    </StackLayout>
                                </ViewCell>
                            </DataTemplate>
                        </ListView.ItemTemplate>
                    </ListView>
                </StackLayout>
    

    and using the Search bar TextChanged event you update your list's Items , but dont Forget to set IsPullToRefreshEnabled="True" in your ListView.

    Like,

    private async void SearchBar_TextChanged(object sender, TextChangedEventArgs e)
                {
                    if (string.IsNullOrWhiteSpace(e.NewTextValue))
                        return;
                    SearchResultListView.BeginRefresh();  // IMPORTANT ***
                    collection.Items = await weatherService.GetForecastByCityOrCountry(e.NewTextValue);
                    SearchResultListView.ItemsSource = collection.Items;
                    SearchResultListView.EndRefresh(); // IMPORTANT ****
                }
    

    Even you dont like to use the SearchBar, this code can be usefull :smile:

    I hope that helps, Mabrouk.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Friday, August 18, 2017 3:01 PM

All replies

  • User192947 posted

    Hello @Zedex ,

    Why you dont use the Search bar? For example if your model is :

     public class WeatherResultModel
                {
                    public string ResultValue { get; set; }
                }
    

    and your collection is :

    public class WeatherResultCollection
            {
                public ObservableCollection<WeatherResultModel> Items { get; set; }
                public WeatherResultCollection()
                {
                    Items = new ObservableCollection<WeatherResultModel>()
                    {
                        new WeatherResultModel() {ResultValue = "Default value"}
                    };
                }
            }
    

    Your View will be like :

    <StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand">
                    <SearchBar Placeholder="Search..." TextChanged="SearchBar_TextChanged"/>
                    <ListView x:Name="SearchResultListView" VerticalOptions="FillAndExpand"
                              IsPullToRefreshEnabled="True">
                        <ListView.ItemTemplate>
                            <DataTemplate>
                                <ViewCell>
                                    <StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand">
                                        <Label Text="{Binding ResultValue}"  TextColor="Black" Font="Bold,14"/>
                                        <!-- ... -->
                                    </StackLayout>
                                </ViewCell>
                            </DataTemplate>
                        </ListView.ItemTemplate>
                    </ListView>
                </StackLayout>
    

    and using the Search bar TextChanged event you update your list's Items , but dont Forget to set IsPullToRefreshEnabled="True" in your ListView.

    Like,

    private async void SearchBar_TextChanged(object sender, TextChangedEventArgs e)
                {
                    if (string.IsNullOrWhiteSpace(e.NewTextValue))
                        return;
                    SearchResultListView.BeginRefresh();  // IMPORTANT ***
                    collection.Items = await weatherService.GetForecastByCityOrCountry(e.NewTextValue);
                    SearchResultListView.ItemsSource = collection.Items;
                    SearchResultListView.EndRefresh(); // IMPORTANT ****
                }
    

    Even you dont like to use the SearchBar, this code can be usefull :smile:

    I hope that helps, Mabrouk.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Friday, August 18, 2017 3:01 PM
  • User339328 posted

    Hi @Mabrouk,

    Thanks for the suggestion with the TextChanged event.

    I've thought of using SearchBar and binding the SearchCommand to trigger the Command in the ViewModel as well.

    I'm still new to this so I was wondering with an Entry view, whether there was a way I could shift the code from CodeBehind into my ViewModel as compared to what I am currently doing now, and also in the use case that I do not want to use the Searchbar as you have mentioned.

    Thanks again!

    Friday, August 18, 2017 3:30 PM
  • User169828 posted

    You should use the SearchBar

    Bind the SearchText to a property in your VM, and the SearchCommand to a method in your VM. no code behind required.

    Friday, August 18, 2017 4:23 PM