1
votes

I am having trouble, with binding properties to a ListView in Xamarin Forms. What I am trying to do is:

        {
            InitializeComponent();
            //Task.Run(async () => await GetTaskDetails());


            GetTasks();

        }

        ObservableCollection<XMCTasks> _userTasks;

        private async void GetTasks()
        {
            using (var client = new HttpClient())
            {
                string userId = "";
                if(Application.Current.Properties["userId"] != null)
                {
                    userId = Application.Current.Properties["userId"].ToString();
                }
                var uri = "http://diplomaxmcws-dev.us-east-2.elasticbeanstalk.com/api/Tasks/GetUserTasks?userId=" + userId;
                var result = await client.GetStringAsync(uri);
                var TaskList = JsonConvert.DeserializeObject<List<XMCTasks>>(result);
                UserTasks = new ObservableCollection<XMCTasks>(TaskList);
            }
        }

        public ObservableCollection<XMCTasks> UserTasks
        {
            get
            {
                return _userTasks;
            }
            set
            {
                _userTasks = value;
                OnPropertyChanged();
            }
        }

Getting a list of objects from a Rest API call, and after that binding those objects to a ListView:

<ListView ItemsSource="{Binding UserTasks}">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <ViewCell.View>
                                <StackLayout>
                                   <!-- <Label Text="{Binding XMCTask_Id, StringFormat='XMCTask_Id: {0:F0)}'}"></Label> -->
                                    <Label Text="{Binding Task_Name, StringFormat='Task_Name: {0:F0)}'}" TextColor="Black" FontSize="Medium"></Label>
                                    <!-- <Label Text="{Binding Task_Description, StringFormat='Task_Description: {0:F0)}'}"></Label>
                                    <Label Text="{Binding Creator_Id, StringFormat='Creator_Id: {0:F0)}'}"></Label> 
                                     <Label Text="{Binding Referencer_Id, StringFormat='Referencer_Id: {0:F0)}'}"></Label>
                                    <Label Text="{Binding XMCPune_Id, StringFormat='XMCPune_Id: {0:F0)}'}"></Label>
                                    <Label Text="{Binding XMCProjekt_Id, StringFormat='XMCProjekt_Id: {0:F0)}'}"></Label>
                                    <Button Text="{Binding XMCTipologjia_Id, StringFormat='XMCTipologjia_Id: {0:F0)}'}"></Button>-->
                                </StackLayout>
                            </ViewCell.View>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>

I don't know if it has to do with the lifecycle of a Xamarin Forms Page. Just to let you know, this page gets loaded after a successful login. Since the process of getting the results from the web service is async it may be possible something to get messed up. Any approach is much appreciated.

1
you haven't told us what the actual problem is. Are you able to get the data from your service? Are you able to find the data to the ItemsSource? Are you having problems binding individual elements in your data template? Where are you setting the BindingContext for the page? And why are calling an async method from the constructor?Jason
Right, I thought it would be implied. Yes my service is returning the data properly. I am calling the async method in the constructor, because I want to show that info(tasks) on the page load. Since I am using xamarin forms the .xaml is responsible for the design and the .cs is kind of controller, thinking of it, MMVM is the way of this design pattern is called. I think that ItemsSource property in the design is enough and declaring a binding context in the "controller" might be at least redundant.Shpend Palushi
You're not answering my questions. Are you getting any rows of data at all? Or are you getting rows without the bound data? Are you setting the BindingContext? If you want to call an async method, do it from OnAppearing, not the constructor.Jason
Yes I was getting data from the service. OnAppearing seems to be working, but from the debugging prespective there were no changes. In the both cases the binding property was getting properly populated. I wanted to to know more about how the things get executed, because seems kinda wired. Anyways thank you!!Shpend Palushi
again, where are you setting BindingContext? Binding will not work without it. Try adding BindingContext = this; in the constructor.Jason

1 Answers

1
votes

The BindingContext property of the target object must be set to the source object.

If you want to use ItemsSource="{Binding UserTasks} in the xaml,you should add BindingContext = this;in your page.cs constructor as Jason said above.

or you could define x:Name for your ListView in xaml,then set ItemSource in your page.cs:

<ListView x:Name="listview">
  ...
</ListView>


private async void GetTasks()
    {
        using (var client = new HttpClient())
        {
            string userId = "";
            if(Application.Current.Properties["userId"] != null)
            {
                userId = Application.Current.Properties["userId"].ToString();
            }
            var uri = "http://diplomaxmcws-dev.us-east-2.elasticbeanstalk.com/api/Tasks/GetUserTasks?userId=" + userId;
            var result = await client.GetStringAsync(uri);
            var TaskList = JsonConvert.DeserializeObject<List<XMCTasks>>(result);
            UserTasks = new ObservableCollection<XMCTasks>(TaskList);
            listview.ItemsSource = UserTasks;
        }
    }