英文:
.NET MAUI ListView not rendering data
问题
I am trying to show the medicineList data in the ListPage.xaml using ListView. I have checked the documentation but I don't find anything noticeable. I have looked at this doc and tried to follow it. But it is not working.
This is ListPage.xaml.cs
using MedicineAlert.Data;
using System.Text.Json;
namespace MedicineAlert.Pages;
public partial class ListPage : ContentPage
{
public List<MedicineData> MedicineList { get; set; }
public ListPage()
{
InitializeComponent();
// Retrieve the app's local data directory path
string localDataDirPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
// Combine the local data directory path with your desired subdirectory
string dbFolderPath = Path.Combine(localDataDirPath, "DB");
string filePath = Path.Combine(dbFolderPath, "data.json");
if(File.Exists(filePath))
{
string json = File.ReadAllText(filePath);
MedicineList = JsonSerializer.Deserialize<List<MedicineData>>(json);
}
}
}
This is ListPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MedicineAlert.Pages.ListPage"
Title="ListPage"
x:Name="MedicinesPage">
<StackLayout>
<ListView
ItemsSource="{Binding MedicineList, Source={x:Reference MedicinesPage}}"
>
<ListView.ItemTemplate>
<DataTemplate>
<TextCell
Text="{Binding MedicineName}"
/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
And this is AppShell.xaml
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="MedicineAlert.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-namespace:MedicineAlert.Pages"
>
<TabBar>
<Tab
Title="Add"
Icon="add.png"
>
<ShellContent
Title="Home"
ContentTemplate="{DataTemplate views:AddPage}"
Route="AddPage"
/>
</Tab>
<Tab
Title="List"
Icon="list.png"
>
<ShellContent
Title="List"
ContentTemplate="{DataTemplate views:ListPage}"
Route="ListPage"
/>
</Tab>
</TabBar>
</Shell>
The ListView in ListPage is not rendering. What could be the problem?
英文:
I am trying to show the medicineList data in the ListPage.xaml using ListView. I have checked the documentation but I don't find anything noticeable. I have looked at this doc and tried to follow it. But it is not working.
This is ListPage.xaml.cs
using MedicineAlert.Data;
using System.Text.Json;
namespace MedicineAlert.Pages;
public partial class ListPage : ContentPage
{
public List<MedicineData> MedicineList { get; set; }
public ListPage()
{
InitializeComponent();
// Retrieve the app's local data directory path
string localDataDirPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
// Combine the local data directory path with your desired subdirectory
string dbFolderPath = Path.Combine(localDataDirPath, "DB");
string filePath = Path.Combine(dbFolderPath, "data.json");
if(File.Exists(filePath))
{
string json = File.ReadAllText(filePath);
MedicineList = JsonSerializer.Deserialize<List<MedicineData>>(json);
}
}
}
This is ListPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MedicineAlert.Pages.ListPage"
Title="ListPage"
x:Name="MedicinesPage">
<StackLayout>
<ListView
ItemsSource="{Binding MedicineList, Source={x:Reference MedicinesPage}}"
>
<ListView.ItemTemplate>
<DataTemplate>
<TextCell
Text="{Binding MedicineName}"
/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
And this is AppShell.xaml
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="MedicineAlert.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-namespace:MedicineAlert.Pages"
>
<TabBar>
<Tab
Title="Add"
Icon="add.png"
>
<ShellContent
Title="Home"
ContentTemplate="{DataTemplate views:AddPage}"
Route="AddPage"
/>
</Tab>
<Tab
Title="List"
Icon="list.png"
>
<ShellContent
Title="List"
ContentTemplate="{DataTemplate views:ListPage}"
Route="ListPage"
/>
</Tab>
</TabBar>
</Shell>
The ListView in ListPage is not rendering. What could be the problem?
答案1
得分: 1
以下是已翻译的内容:
`ListView` 未渲染的原因有两个:
1. `internal List<MedicineData> medicineList` 是一个字段,但它应该是一个属性,因为只有属性可以在绑定表达式中使用。
2. 您的 `ItemsSource` 绑定没有指向代码后端。
首先,将字段更改为属性:
```c#
public List<MedicineData> MedicineList { get; }
然后,将 InitializeComponent();
调用移到构造函数的末尾:
public ListPage()
{
// 检索应用程序的本地数据目录路径
string localDataDirPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
// 将本地数据目录路径与所需的子目录相结合
string dbFolderPath = Path.Combine(localDataDirPath, "DB");
string filePath = Path.Combine(dbFolderPath, "data.json");
if(File.Exists(filePath))
{
string json = File.ReadAllText(filePath);
MedicineList = JsonSerializer.Deserialize<List<MedicineData>>(json);
}
InitializeComponent();
}
这是必需的,因为在您的情况下,绑定仅会在 InitializeComponent();
调用期间进行一次评估。
最后,根据以下方式更新 XAML,使用绑定 Source
,它指向页面的名称:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MedicineAlert.Pages.ListPage"
Title="ListPage"
x:Name="MedicinesPage">
<StackLayout>
<ListView
ItemsSource="{Binding MedicineList, Source={x:Reference MedicinesPage}}">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell
Text="{Binding MedicineName}"
/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
将页面绑定到其自己的代码后端也是一种方法,通过设置 BindingContext = this;
,但在这种方法中是不必要的。
注意: 不建议在构造函数内加载数据。您可能需要重新思考您的代码设计。如果需要频繁更新 List
,应该将其替换为 ObservableCollection
,并使属性本身也可观察。这是MVVM 模式的常见用例。
英文:
The reason the ListView
is not rendering is two-fold:
- The
internal List<MedicineData> medicineList
is a field, but it should be a property as only properties can be used in binding expressions - Your
ItemsSource
binding is not pointing to the code-behind
First, change the field into a property:
public List<MedicineData> MedicineList { get; }
after that, move the InitializeComponent();
call to the end of the constructor:
public ListPage()
{
// Retrieve the app's local data directory path
string localDataDirPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
// Combine the local data directory path with your desired subdirectory
string dbFolderPath = Path.Combine(localDataDirPath, "DB");
string filePath = Path.Combine(dbFolderPath, "data.json");
if(File.Exists(filePath))
{
string json = File.ReadAllText(filePath);
MedicineList = JsonSerializer.Deserialize<List<MedicineData>>(json);
}
InitializeComponent();
}
This is required, because in your case the binding will only get evaluated once and that happens during the InitializeComponent();
call.
Finally, update the XAML as follows using a binding Source
which points to the name of the page:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MedicineAlert.Pages.ListPage"
Title="ListPage"
x:Name="MedicinesPage">
<StackLayout>
<ListView
ItemsSource="{Binding MedicineList, Source={x:Reference MedicinesPage}}">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell
Text="{Binding MedicineName}"
/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
Binding a page to its own code behind is also an option by setting BindingContext = this;
, but that's not necessary with this approach.
Note: It's not recommended to load data inside a constructor. You may want to rethink your code design here. If you need to update the List
frequently, you should replace it with an ObservableCollection
and make the property itself also observable. This is a common use case for the MVVM pattern.
答案2
得分: 0
以下是您代码中需要翻译的部分:
- 尝试将以下代码
internal List<MedicineData> medicineList;
替换为
public List<MedicineData> medicineList { get; set; }
- 为您的页面设置
BindingContext
:
public partial class ListPage : ContentPage
{
//internal List<MedicineData> medicineList;
public List<MedicineData> medicineList { get; set; }
public ListPage()
{
InitializeComponent();
// 获取应用程序的本地数据目录路径
string localDataDirPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
// 将本地数据目录路径与所需的子目录相结合
string dbFolderPath = Path.Combine(localDataDirPath, "DB");
string filePath = Path.Combine(dbFolderPath, "data.json");
if(File.Exists(filePath))
{
string json = File.ReadAllText(filePath);
medicineList = JsonSerializer.Deserialize<List<MedicineData>>(json);
}
// 在此处设置BindingContext
this.BindingContext = this;
}
}
注意:
您可以重新检查是否已正确获取medicineList
的数据。
英文:
There are several problems in your code.
- Try to replace the following code
internal List<MedicineData> medicineList;
with
public List<MedicineData> medicineList { get; set; }
- Set the
BindingContext
for your page:
public partial class ListPage : ContentPage
{
//internal List<MedicineData> medicineList;
public List<MedicineData> medicineList { get; set; }
public ListPage()
{
InitializeComponent();
// Retrieve the app's local data directory path
string localDataDirPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
// Combine the local data directory path with your desired subdirectory
string dbFolderPath = Path.Combine(localDataDirPath, "DB");
string filePath = Path.Combine(dbFolderPath, "data.json");
if(File.Exists(filePath))
{
string json = File.ReadAllText(filePath);
medicineList = JsonSerializer.Deserialize<List<MedicineData>>(json);
}
// set BindingContext here
this.BindingContext = this;
}
}
Note:
You can recheck if you have get the correct data for medicineList
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论