简体   繁体   中英

How to access a ListView from another page?(Xamarin Forms)

I would like to modify the content of a list View from my MainPage. The list view is in another page called LoadResultsPage. Here is the button in the main page which calls the function:

<Button Text="Load Results" Clicked="FetchData"></Button>

Here is the function which is called:

public async void FetchData(object sender, System.EventArgs e)
    {
        /* string apiUrl = null;
         if (Device.RuntimePlatform == Device.Android)
             apiUrl = "https://10.0.2.2:5001/api";
         else if (Device.RuntimePlatform == Device.iOS)
             apiUrl = "https://localhost:5001/api";
         else
             throw new Exception();*/
        await Navigation.PushAsync(new LoadResultsPage());
        var httpClient = new HttpClient();
        var response = await httpClient.GetStringAsync("http://localhost:5001/api/Calcs");
        var login = JsonConvert.DeserializeObject<List<Calc>>(response);
        Lista.ItemsSource = login;
    }

Here Lista(at the bottom of the function) is not recognized and the error is : "The name 'Lista' does not exist in the current context"

And finally here is the content of the page LoadResultsPage where the list view that i want to modify is:

<?xml version="1.0" encoding="utf-8" ?>
  <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="Calculator.Views.LoadResultsPage">
<Grid  VerticalOptions="FillAndExpand">
    <ListView x:Name="Lista" >
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell >
                    <StackLayout >
                        <Label Text="{Binding Id}" TextColor="Black"></Label>
                        <Label Text="{Binding Value}"></Label>
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Grid>

How do i populate the two labels with the info in the variable "login" ?

Please kindly read about MVVM that my change your concept globally. It is considered not a best style to access ui elements between pages.

Anyway directly answering your question use some static model to exchange data globally inside app.

    public class Exchange
    {
        private static Exchange _instance;
        public static Exchange Data
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new Exchange();
                }
                return _instance;
            }
        }

        public string Buffer { get; set; }

        public ListView MyListView { get; set; }

    }

Example: Exchange.Data.Buffer will be accessible from anywhere.

For your ListView in its page constuctor after the InitializeComponent(); set

Exchange.Data.MyListView = Lista;

Now the important part that if you access your ListView from another page you have to do it on UI thread. Example:

        Device.BeginInvokeOnMainThread(() =>
        {
            // Update the UI
            Exchange.Data.MyListView.ItemsSource = whatever;
        });

The name field is not a public property, so by default it can not be accessed outside page.

There are two options for you question:

  1. Once you get the data (in your case "login") then only you navigate to LoadResultsPage and pass login as parameter and in LoadResultsPage, you will have access to "Lista".

  2. Make a public property in LoadResultsPage, after getting "login", assign "login" to that property and in LoadResultsPage set Lista.ItemSource to that property.

Here suggesting that passing login data for LoadResultsPage , then can show the data when LoadResultsPage appears.

For example, modifying FetchData method as follow:

public async void FetchData(object sender, System.EventArgs e)
{
    
    var httpClient = new HttpClient();
    var response = await httpClient.GetStringAsync("http://localhost:5001/api/Calcs");
    var login = JsonConvert.DeserializeObject<List<Calc>>(response);
    //Lista.ItemsSource = login;

    await Navigation.PushAsync(new LoadResultsPage(login));
}

Then in LoadResultsPage.xaml.cs :

public partial class DetailPage : ContentPage
{
    public DetailPage(Model login)
    {
        InitializeComponent();
        Lista.ItemsSource = login;
    }
}

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