ListView 不显示来自 ViewModel 的 ObservableProperty 绑定

问题描述 投票:0回答:1

我是 .NET MAUI/MVVM/SQLite 和 C# 的新手。我正在尝试利用 ViewModel 来绑定模型类中的数据。我可以使用模型命名空间作为我的绑定属性,它会在我的列表视图中显示数据。然而,一旦我尝试使用我的 ViewModel,它就不再显示。

CRUDView XAML 工作

        <Frame Grid.Row="6" Grid.Column="1" Grid.ColumnSpan="3" BackgroundColor="#B1C0C9" BorderColor="#7989A3">
            <ScrollView Orientation="Vertical">
                <ListView x:Name="listView" 
                          BackgroundColor="Gray" 
                          HasUnevenRows="True"
                          SeparatorVisibility="Default"
                          ItemTapped="listView_ItemTapped"
                          FlexLayout.Grow="1"
                          >
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <ViewCell>
                                <VerticalStackLayout Padding="5">
                                    <Label Text="{Binding Question}"
                                           FontSize="17" 
                                           FontFamily="OCRA" 
                                           TextColor="Black"/>
                                    <Grid>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="50"/>
                                            <ColumnDefinition Width="*"/>
                                            <ColumnDefinition Width="*"/>
                                            <ColumnDefinition Width="Auto"/>
                                        </Grid.ColumnDefinitions>
                                        <Label Text="{Binding Id}"
                                               FontSize="10" 
                                               FontFamily="OCRA" 
                                               TextColor="Black"
                                               Grid.Column="0"
                                               />
                                        <Label Text="{Binding Answer}"
                                               FontSize="15" 
                                               FontFamily="OCRA" 
                                               TextColor="White"
                                               Grid.Column="1"
                                               Padding="10"/>
                                        <Label Text="{Binding Difficulty}"
                                               FontSize="15" 
                                               FontFamily="OCRA" 
                                               TextColor="Black"
                                               Grid.Column="3"
                                               Padding="10"/>
                                    </Grid>
                                    
                                </VerticalStackLayout>
                            </ViewCell>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
            </ScrollView>

        </Frame>

Showing data in ListView

当我恢复使用 ViewModel 进行数据绑定时:

CRUD查看XAML

<Frame Grid.Row="6" Grid.Column="1" Grid.ColumnSpan="3" BackgroundColor="#B1C0C9" BorderColor="#7989A3">
    <ScrollView Orientation="Vertical">
        <ListView x:Name="listView" 
                  BackgroundColor="Gray" 
                  HasUnevenRows="True"
                  SeparatorVisibility="Default"
                  ItemTapped="listView_ItemTapped"
                  FlexLayout.Grow="1"
                  ItemsSource="{Binding Flashcards}">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="vm:CRUDViewModel">
                    <ViewCell>
                        <VerticalStackLayout Padding="5">
                            <Label Text="{Binding Flashcard.Question}"
                                   FontSize="17" 
                                   FontFamily="OCRA" 
                                   TextColor="Black"/>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="50"/>
                                    <ColumnDefinition Width="*"/>
                                    <ColumnDefinition Width="*"/>
                                    <ColumnDefinition Width="Auto"/>
                                </Grid.ColumnDefinitions>
                                <Label Text="{Binding Flashcard.Id}"
                                       FontSize="10" 
                                       FontFamily="OCRA" 
                                       TextColor="Black"
                                       Grid.Column="0"
                                       />
                                <Label Text="{Binding Flashcard.Answer}"
                                       FontSize="15" 
                                       FontFamily="OCRA" 
                                       TextColor="White"
                                       Grid.Column="1"
                                       Padding="10"/>
                                <Label Text="{Binding Flashcard.Difficulty}"
                                       FontSize="15" 
                                       FontFamily="OCRA" 
                                       TextColor="Black"
                                       Grid.Column="3"
                                       Padding="10"/>
                            </Grid>
                            
                        </VerticalStackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </ScrollView>

</Frame>

视图模型

namespace cadflash.ViewModels
{
    public partial class CRUDViewModel : ObservableObject
    {
        [ObservableProperty]
        public ObservableCollection<Flashcard> flashcards = new();

        [ObservableProperty]
        public Flashcard flashcard = new();
        
        public CRUDViewModel()
        {
            Flashcard = new Flashcard();
            Flashcards = [];
        }

毛伊岛计划

MauiProgram

    public static class MauiProgram
    {
        public static MauiApp CreateMauiApp()
        {
            var builder = MauiApp.CreateBuilder();
            builder
                .UseMauiApp<App>()
                .UseMauiCommunityToolkit()
                .ConfigureFonts(fonts =>
                {
                    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                    fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
                    fonts.AddFont("OCRAEXT.ttf", "OCRA");
                });

            builder.Services.AddSingleton<LocalDbService>();
            builder.Services.AddTransient<HomeView>();
            builder.Services.AddTransient<DifficultyView>();
            builder.Services.AddTransient<CRUDView>();
            builder.Services.AddTransient<CRUDViewModel>();
            builder.Services.AddTransient<DifficultyViewModel>();
            builder.Services.AddTransient<HomeViewModel>();


#if DEBUG
            builder.Logging.AddDebug();
#endif

            return builder.Build();
        }
    }
}

CRUDView.cs

CRUDView.xaml.cs

public partial class CRUDView : ContentPage
{
    CRUDViewModel viewModel;
    private readonly LocalDbService localDbService; // This is the service that is used to interact with the local database
    private int _editFlashcardId; // This is the ID of the flashcard that is being edited
    public CRUDView(LocalDbService localDbService)
    {
        InitializeComponent();
        BindingContext = new CRUDViewModel();
        this.localDbService = localDbService;
        Task.Run(async () => await localDbService.GetFlashcardsAsync());
    }

    protected override async void OnAppearing()
    {
        base.OnAppearing();
        listView.ItemsSource = await localDbService.GetFlashcardsAsync();
    }

No data in ListView

为了让数据显示在列表视图中,我们经历了一周的痛苦。今天我弄清楚了如何直接从模型类绑定数据。理想情况下,我想使用 ViewModel 绑定...

mvvm data-binding maui observablecollection
1个回答
0
投票

您的代码中的用法存在一些问题。

首先,由于您尝试使用MVVM,因此您需要将

localDbService
的相关代码添加到您的MVVM模型中。例如,您可以将
localDbService
和加载数据方法添加到 MVVM 模型。

    //private readonly LocalDbService localDbService; // This is the service that is used to interact with the local database

    public CRUDViewModel()
    {
        //initialize localDbService and load data
        //this.localDbService = localDbService;
    }

第二,既然你给你的

ItemsSource="{Binding Flashcards}"
设置了
ListView
,那么ListView的
DataTemplate
的数据类型应该是
Flashcard
而不是
<DataTemplate x:DataType="vm:CRUDViewModel">

第三,绑定时请去掉前缀

Flashcard
(如
<Label Text="{Binding Flashcard.Id}"
)。

我用一些假数据实现了这个功能。

可以参考以下代码:

CRUDViewModel.cs

public partial class CRUDViewModel:ObservableObject
{
    [ObservableProperty]
    public ObservableCollection<Flashcard> flashcards = new();

    [ObservableProperty]
    public Flashcard flashcard = new();


    //private readonly LocalDbService localDbService; // This is the service that is used to interact with the local database


    public CRUDViewModel()
    {
        Flashcard = new Flashcard();
        Flashcards = [];

        //initialize localDbService and load data
        //this.localDbService = localDbService;
       
        GetData();
    }

    public async void GetData() {

        //List<Flashcard>  datas = await localDbService.GetFlashcardsAsync());

        // add the data to Flashcards
        //foreach (Flashcard flashcard in datas) {
        //    Flashcards.Add(flashcard);
        //}

        //add some fake data to variable Flashcards
        Flashcards.Add(new Flashcard { Id = 01, Question = "1+ 1 = ", Answer = "2", Difficulty = "easy" });
        Flashcards.Add(new Flashcard { Id = 02, Question = "1+ 3 = ", Answer = "4", Difficulty = "easy" });
        Flashcards.Add(new Flashcard { Id = 03, Question = "123+163 = ", Answer = "286", Difficulty = "difficult" });

    }
}

主页.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"
             
             xmlns:models="clr-namespace:MauiMvvmListApp0407.Models"
             x:Class="MauiMvvmListApp0407.MainPage">

    <Frame Grid.Row="6"  Grid.Column="1" Grid.ColumnSpan="3" BackgroundColor="#B1C0C9" BorderColor="#7989A3">
            <ListView x:Name="listView"
                  BackgroundColor="Gray"
                  HasUnevenRows="True"
                  SeparatorVisibility="Default"
                  ItemsSource="{Binding Flashcards}">
                <ListView.ItemTemplate>
                <DataTemplate x:DataType="models:Flashcard">
                        <ViewCell>
                            <VerticalStackLayout Padding="5">
                                <Label Text="{Binding Question}"
                                   FontSize="17"
                                   FontFamily="OCRA"
                                   TextColor="Black"/>
                                <Grid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="50"/>
                                        <ColumnDefinition Width="*"/>
                                        <ColumnDefinition Width="*"/>
                                        <ColumnDefinition Width="Auto"/>
                                    </Grid.ColumnDefinitions>
                                    <Label Text="{Binding Id}"
                                       FontSize="10"
                                       FontFamily="OCRA"
                                       TextColor="Black"
                                       Grid.Column="0"
                                       />
                                    <Label Text="{Binding Answer}"
                                       FontSize="15"
                                       FontFamily="OCRA"
                                       TextColor="White"
                                       Grid.Column="1"
                                       Padding="10"/>
                                    <Label Text="{Binding Difficulty}"
                                       FontSize="15"
                                       FontFamily="OCRA"
                                       TextColor="Black"
                                       Grid.Column="3"
                                       Padding="10"/>
                                </Grid>

                            </VerticalStackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
    </Frame>
</ContentPage>

MainPage.xaml.cs

public partial class MainPage : ContentPage
{
    CRUDViewModel viewModel;
    public MainPage()
    {
        InitializeComponent();

        viewModel = new CRUDViewModel();
        this.BindingContext = viewModel;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.