I am trying to create a <ListView>
with XAML. The list is supposed to show the contents of a list of the class Task
.
taskView.ItemsSource = company.tasks;
The version of XAML I am using is the one contemplated on MAUI therefore most tutorials show elements than are not included in the XAML version used.
I tried to do it as following:
<ListView x:Name="taskView"
Margin="120,0,0,60"
ItemsSource="{Binding tasks}"
ItemSelected="taskView_SelectionChanged">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding name}"/>
<TextCell Text="{Binding status}"/>
<TextCell Text="{Binding dedaline}"/>
<TextCell Text="{Binding description}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
But it did not work. It would neither open the app nor throw an exception.
If I leave only one <TextCell>
, it opens and shows (only the name). How can I show more details?
Here is the class Task
:
public class Task
{
public Task(string name, List<string> departments, Status status, DateOnly deadline, string description)
{
this.name = name;
this.departments = departments;
this.status = status;
this.deadline = deadline;
this.description = description;
}
public string name { get; private set; }
public List<string> departments { get; private set; } = new List<string>();
public Status status { get; private set; }
public DateOnly deadline { get; private set; }
public Employee? author { get; set; }
public string description { get; private set; }
public List<Employee> employees { get; private set; } = new List<Employee>();
}
I am fairly new to XAML and would candidly appreciate some help. Thank you.
CodePudding user response:
First an irrelevant thing. The class "Task" may cause you problem because you already have System.Threading.Task
in .net.
You shouldn't bind the ListView (or CollectionView) to a source twice for the same purpose as @Jason said.
XAML FILE
<ContentPage
x:Class="MauiApp.MainPage"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:models="clr-namespace:MauiApp.Models"
xmlns:views="clr-namespace:MauiApp.Views"
x:DataType="views:MainPage">
<CollectionView
ItemsSource="{Binding Tasks}">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="models:Task">
<VerticalStackLayout Margin="15">
<Entry Text="{Binding name}" />
<Entry Text="{Binding status}" />
<Entry Text="{Binding deadline}" />
<Entry Text="{Binding description}" />
</VerticalStackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ContentPage>
Check the XML namespaces (xmlns). I assumed you have your Task model inside "Models" folder and your views inside "Views" folder. You need this import because your content page's datatype is binded with MainPage
, but your CollectionView is binded with Task
class.
Inside DataTemplate you can have only 1 item. So you should choose a container item, like VerticalStackLayout
in this answer.
CLASS FILE
public partial class MainPage : ContentPage
{
public ObservableCollection<Task> Tasks { get; set; } = new ObservableCollection<Task>();
public MainPage()
{
InitializeComponent();
BindingContext = this;
Tasks.Add(new Task("task 1", new List<string>() { "dep1", "dep2" }, "status 1", DateOnly.MinValue, "description 1"));
Tasks.Add(new Task("task 2", new List<string>() { "dep3", "dep4" }, "status 2", DateOnly.MinValue, "description 2"));
}
}
In your class you could use ObservableCollection
and you must bind Context with BindingContext = this;
If you are using MVVM, than you can bind that to your ViewModel.
This should work as expected, although you may need to class OnPropertyChanged if needed.
CodePudding user response:
a ListView
's DataTemplate
can only contains a single child element. If you want to have multiple data elements, use a ViewCell instead of a TextCell
and build your own custom layout
<ViewCell>
<StackLayout BackgroundColor="#eee"
Orientation="Vertical">
<StackLayout Orientation="Horizontal">
<Image Source="{Binding image}" />
<Label Text="{Binding title}"
TextColor="#f35e20" />
<Label Text="{Binding subtitle}" HorizontalOptions="EndAndExpand"
TextColor="#503026" />
</StackLayout>
</StackLayout>
</ViewCell>