How to get data binding object in "DataTemplate"?

валера карманов 396 Reputation points
2024-10-02T06:20:01.3066667+00:00

Hello. I fill the "CollectionView" element with data from "HttpClient" and when outputting to the page I want to access the object that contains information about one object.

How can I do this in the "DataTemplate" class that is specified in the "ItemTemplate" property? Maybe the "ItemTemplate" property can be filled in some other way without data binding?

As for the object that I mentioned, this is the "Person" class, it is used in the collection for the "ItemsSource" property.

private VerticalStackLayout _content;
private CollectionView _collection;
private RefreshView _refresh;

private HttpClient _client;
private JsonSerializerOptions _serializerOptions;

public List<Person> _persons { get; private set; }

public MainPage()
{
	_content = new VerticalStackLayout { Padding = 10 };

	_collection = new CollectionView {
		EmptyView = "Persons empty",
		RemainingItemsThreshold = 5
	};

	RefreshDataAsync();

	_collection.ItemTemplate = new DataTemplate(() =>
	{
		var labelName = new Label
		{
			TextColor = Color.FromArgb("#00415a"),
			FontSize = 10
		};

		labelName.SetBinding(Label.TextProperty, "Name");

		var labelCompany = new Label
		{
			TextColor = Color.FromArgb("#00415a"),
			FontSize = 12,
			FontAttributes = FontAttributes.Bold
		};

		labelCompany.SetBinding(Label.TextProperty, "Company");

		return new Border
		{
			Padding = 5,
			Stroke = Color.FromArgb("#D1D5DB"),
			StrokeShape = new RoundRectangle { CornerRadius = 4 },
			Content = new StackLayout {
				Children = {
					labelName, labelCompany
				}
			}
		};
	});

	_content.Add(_collection);
	Content = new ScrollView { Content = _content };
}

private async void RefreshDataAsync()
{
	_persons = new List<Person>();
	_client = new HttpClient();

	_serializerOptions = new JsonSerializerOptions
	{
		PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
		WriteIndented = true
	};

	HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "https://example.ru");

	try
	{
		HttpResponseMessage response = await  _client.SendAsync(request);

		if (response.IsSuccessStatusCode)
		{
			string content = await  response.Content.ReadAsStringAsync();

			_persons = JsonSerializer.Deserialize<List<Person>>(content, _serializerOptions);
			_collection.ItemsSource = _persons;
		}
	}
	catch (Exception ex)
	{
		Debug.WriteLine("Error : " + ex.Message);
	}
}

public class Person
{
	public string Name { get; set; } = "";
	public int Age { get; set; }
	public string Company { get; set; } = "";
}
.NET MAUI
.NET MAUI
A Microsoft open-source framework for building native device applications spanning mobile, tablet, and desktop.
3,579 questions
{count} votes

Accepted answer
  1. Leon Lu (Shanghai Wicresoft Co,.Ltd.) 76,391 Reputation points Microsoft Vendor
    2024-10-02T08:16:23.42+00:00

    Hello,

    ===================Update====================

    but if you do not use the "HeightRequest" property, the list does not scroll, how to fix this?

    You can replace the VerticalStackLayout with a Grid. See this tip from Collectionview document

    Firstly, please donot use ScrollView as the rootView, if you set it as rootView, Collectionview's Scroll Event will not execute and set a specific value for Collectionview's HeightRequest property.

    I add the Scrolled event for Collectionview and set the rootview to the stacklayout like following code.

    _collection = new CollectionView
    {
         EmptyView = "Persons empty",
         RemainingItemsThreshold = 5,
         HeightRequest = 200,
    };
    
    ...
    
    _collection.Scrolled += _collection_Scrolled;
     
             
    _content.Add(_collection);
    Content = _content ;
    

    Next, you can get all of appeared Person objects by FirstVisibleItemIndex and LastVisibleItemIndex.

    private void _collection_Scrolled(object? sender, ItemsViewScrolledEventArgs e)
    {
    
     
         var FirstIndex = e.FirstVisibleItemIndex;
         var LastIndex = e.LastVisibleItemIndex;
     
    
    for (var i = FirstIndex; i <= LastIndex; i++) {
     //get all of appeared Person objects
          Person appearPerson =  _persons[i];
      }
    
    
    }
    

    Best Regards,

    Leon Lu


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.