You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MAUI中ListView绑定ViewModel后添加数据无法刷新的问题

问题:ListView绑定ObservableCollection后无法刷新界面

尝试通过XAML将ListView(AllDocuments)绑定到DocumentSummary对象集合,但ListView始终无法刷新:MainPage.xaml.cs的OnButtonClick方法能正常获取数据,每次点击按钮时AllDocuments对象都能正确更新且数据有效,但向AllDocuments添加新项后,ListView并未同步更新,绑定配置存在问题。

当前代码

ViewModel 代码

using CommunityToolkit.Mvvm.Input;
using System.Windows.Input;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Diagnostics;

namespace peMove.Maui.ViewModels
{
    public class DocumentSummary
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public string DocType { get; set; }
        public decimal Onhand { get; set; }
        public string Note { get; set; }  
        public Color Color { get; set; }
    }
    public class DocsViewModel : IQueryAttributable
    {
        public ObservableCollection<DocumentSummary> AllDocuments { get; }
        public DocsViewModel() 
        {
            this.AllDocuments = new();
            this.DocSummary = new();
        }

        public void AddDocument(Document _doc)
        {
            //DocSummary = new();
            DocSummary.Id = _doc.Id1;
            DocSummary.Name = _doc.Name;
            DocSummary.DocType = "Part";
            DocSummary.Onhand = _doc.Onhand;
            DocSummary.Note = "Some note goes here";
            DocSummary.Color = MauiProgram.colorPart;
            this.AllDocuments.Add(DocSummary);
            Debug.Print("");
        }
    }
}

MainPage.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:viewModels="clr-namespace:peMove.Maui.ViewModels"
             x:Class="peMove.Maui.Pages.MainPage"
             x:DataType="viewModels:DocsViewModel"
             Title="Lookup">

    <ContentPage.BindingContext>
        <viewModels:DocsViewModel/>
    </ContentPage.BindingContext>

    <VerticalStackLayout Margin="20">
        <Button Text="Load"
                VerticalOptions="Center"
                HorizontalOptions="Center"
                Clicked="OnButtonClicked"/>
        <Entry x:Name="documentId"
               FontSize="24"
               Keyboard="Chat"
               Placeholder="Enter\Scan Id"
               ClearButtonVisibility="WhileEditing"/>
        <ListView ItemsSource="{Binding AllDocuments}" 
                HasUnevenRows="True" 
                VerticalOptions="FillAndExpand"
                SeparatorColor="Black">
            <!--<ListView.BindingContext>
                <viewModels:DocsViewModel/>
            </ListView.BindingContext>-->

            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Grid RowDefinitions="Auto"
                              ColumnSpacing="5"
                              ColumnDefinitions="Auto,*,Auto" Margin="10,0">
                              
                            <!--Column 1-->
                            <Border
                            Grid.Column="0"
                            WidthRequest="40" 
                            StrokeShape="RoundRectangle 20,20,20,20"
                            VerticalOptions="Center"
                            HorizontalOptions="Center"
                            BackgroundColor="LightBlue"
                            Padding="12,6"
                            Margin="10"
                            HeightRequest="40">
                                <Label  FontSize="20"
                                    Text="{Binding DocSummary.DocType}"
                                    TextColor="#FFFFFFDE"
                                    VerticalOptions="Center" 
                                    HorizontalOptions="Center"/>
                            </Border>

                            <!--Column 2-->
                            <VerticalStackLayout Grid.Column="1" 
                                                 Spacing="5"
                                                 Margin="0,0,0,0">
                                <Label Text="{Binding DocSummary.Id}" 
                                            HeightRequest="20"
                                              VerticalOptions="Start"
                                              HorizontalOptions="Start"
                                              FontSize="14"
                                              FontAttributes="Bold"
                                              TextColor="Black" VerticalTextAlignment="Start"/>
                                <Label Text="{Binding DocSummary.Name}"
                                            HeightRequest="20"
                                              HorizontalOptions="Start"
                                              VerticalOptions="Start"
                                              TextColor="{AppThemeBinding Light='#99000000'}" 
                                              FontSize="16"/>
                                <Label Text="{Binding DocSummary.Note}"
                                              HorizontalOptions="Start"
                                              VerticalOptions="StartAndExpand"
                                              LineBreakMode="WordWrap"
                                              TextColor="Black" 
                                              FontSize="12"/>
                            </VerticalStackLayout>

                            <!--Column 3-->
                            <Label Grid.Column="2"
                               Text="{Binding DocSummary.Onhand, StringFormat='{0:F2}'}"
                               HorizontalOptions="EndAndExpand"
                               VerticalOptions="Start"
                               TextColor="Black" 
                               FontSize="18"/>
                        </Grid>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </VerticalStackLayout>
</ContentPage>

MainPage.xaml.cs

using peMove.Maui.Models;
using peMove.Maui.ViewModels;
using System.Diagnostics;
using System.Text;

namespace peMove.Maui.Pages
{

    public partial class MainPage : ContentPage
    {
        int count = 0;
        DocsViewModel docs = new();

        public MainPage()
        {
            InitializeComponent();
            //this.BindingContext= docs;
        }

        async void OnButtonClicked(object sender, EventArgs args)
        {
            DocId key = new DocId();
            key.Id1 = "Default";
            key.Id2 = "WF201B";
            key.Id3 = "000";
            ErpPart erpDocument = new();
            erpDocument = await ErpPart.LoadAsync(key);

            // This is working and returning a valid ErpPart.

            Document _doc = new();

            _doc.Id1=erpDocument.Part.Id1;
            _doc.Name=erpDocument.Part.Name;
            _doc.DocType = erpDocument.Part.Type;
            _doc.Onhand=0;
            _doc.UofM=erpDocument.Part.UofM;
            _doc.Value01 = erpDocument.Part.Source;
            _doc.Value02 = erpDocument.Part.Purchased;
            _doc.Status=erpDocument.Part.Status;

            docs.AddDocument(_doc);
        }
    }
}

问题根源及修复方案

1. BindingContext实例不统一

XAML中通过<ContentPage.BindingContext>创建了一个独立的DocsViewModel实例,而MainPage.xaml.cs中又new了另一个docs实例,两者完全独立。修改cs中的docs不会影响XAML绑定的实例,导致界面无反应。

修复:
在MainPage构造函数中设置BindingContext为当前页面的docs实例,移除XAML中的<ContentPage.BindingContext>节点:

public MainPage()
{
    InitializeComponent();
    BindingContext = docs;
}

2. DataTemplate绑定路径错误

ListView的ItemsSource绑定的是AllDocuments(ObservableCollection<DocumentSummary>),因此每个Item的BindingContext是DocumentSummary对象,但XAML中错误使用{Binding DocSummary.XXX}路径,应该直接绑定DocumentSummary的属性。

修复:
修改ItemTemplate中的绑定路径,并添加x:DataType指定Item类型:

<ListView.ItemTemplate>
    <DataTemplate x:DataType="viewModels:DocumentSummary">
        <ViewCell>
            <Grid RowDefinitions="Auto"
                  ColumnSpacing="5"
                  ColumnDefinitions="Auto,*,Auto" Margin="10,0">
                  
                <!--Column 1-->
                <Border
                Grid.Column="0"
                WidthRequest="40" 
                StrokeShape="RoundRectangle 20,20,20,20"
                VerticalOptions="Center"
                HorizontalOptions="Center"
                BackgroundColor="LightBlue"
                Padding="12,6"
                Margin="10"
                HeightRequest="40">
                    <Label  FontSize="20"
                        Text="{Binding DocType}"
                        TextColor="#FFFFFFDE"
                        VerticalOptions="Center" 
                        HorizontalOptions="Center"/>
                </Border>

                <!--Column 2-->
                <VerticalStackLayout Grid.Column="1" 
                                     Spacing="5"
                                     Margin="0,0,0,0">
                    <Label Text="{Binding Id}" 
                                HeightRequest="20"
                                  VerticalOptions="Start"
                                  HorizontalOptions="Start"
                                  FontSize="14"
                                  FontAttributes="Bold"
                                  TextColor="Black" VerticalTextAlignment="Start"/>
                    <Label Text="{Binding Name}"
                                HeightRequest="20"
                                  HorizontalOptions="Start"
                                  VerticalOptions="Start"
                                  TextColor="{AppThemeBinding Light='#99000000'}" 
                                  FontSize="16"/>
                    <Label Text="{Binding Note}"
                                  HorizontalOptions="Start"
                                  VerticalOptions="StartAndExpand"
                                  LineBreakMode="WordWrap"
                                  TextColor="Black" 
                                  FontSize="12"/>
                </VerticalStackLayout>

                <!--Column 3-->
                <Label Grid.Column="2"
                   Text="{Binding Onhand, StringFormat='{0:F2}'}"
                   HorizontalOptions="EndAndExpand"
                   VerticalOptions="Start"
                   TextColor="Black" 
                   FontSize="18"/>
            </Grid>
        </ViewCell>
    </DataTemplate>
</ListView.ItemTemplate>

3. AddDocument方法复用同一个实例

DocsViewModel中DocSummary是类级别的字段,每次调用AddDocument只是修改该实例的属性,再添加到集合中,导致集合中所有项都是同一个对象,既不符合预期也可能引发界面异常。

修复:
每次添加时创建新的DocumentSummary实例:

public void AddDocument(Document _doc)
{
    var docSummary = new DocumentSummary
    {
        Id = _doc.Id1,
        Name = _doc.Name,
        DocType = "Part",
        Onhand = _doc.Onhand,
        Note = "Some note goes here",
        Color = MauiProgram.colorPart
    };
    AllDocuments.Add(docSummary);
}

内容的提问来源于stack exchange,提问作者BumpaRoy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 11:17:02