.NET Maui PropertyChanged事件未更新XAML视图

pokxtpni  于 2022-12-07  发布在  .NET
关注(0)|答案(1)|浏览(215)

我正在构建一个Maui Blazor应用程序,但是我需要实现一个QR阅读器,这要求我在XAML中使用它。在实现QR阅读器之前,我测试了如何使用简单的XAML标签来使用XAML绑定,但是当支持的App State服务类属性更改时,我无法更新标签。但是标签确实获得了初始值,所以我假设绑定在加载时工作。此外,当从Blazor界面更改属性时,我可以看到调用了OnPropertyChanged方法,并且值是正确的。
我下面的例子:https://learn.microsoft.com/en-us/dotnet/maui/xaml/fundamentals/mvvm
这是我的Maui计划:

namespace MyNamespace;

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
    var builder = MauiApp.CreateBuilder();

    builder
        .UseMauiApp<App>()
        .UseBarcodeReader()
        .ConfigureFonts(fonts =>
        {
            fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
        });

    builder.Services.AddScoped(sp => new HttpClient
    {
        Timeout = TimeSpan.FromMinutes(10)
    });
    builder.Services.AddSingleton<MainPage>();
    builder.Services.AddBlazorWebViewDeveloperTools();
    builder.Services.AddMauiBlazorWebView();        
    builder.Services.AddScoped<IAuthenticationService, AuthenticationService>();
    builder.Services.AddScoped<AuthenticationStateProvider, AuthStateProvider>();
    builder.Services.AddAuthorizationCore();
    builder.Services.AddScoped<AppStateService>();
    builder.Services.AddScoped<APIService>();
    builder.Services.AddScoped<CommonMethods>();

    string dbPath = Path.Combine(FileSystem.AppDataDirectory, "LocalDb.db3");
    builder.Services.AddDbContext<LocalDb>(options => options.UseSqlite($"Filename={dbPath}"));

    return builder.Build();
    }
}

这是我的应用程序状态服务类:

namespace MyNamespace.Data
{

public class AppStateService : INotifyPropertyChanged
{
    //My global app state management 
    private SortedLocalDb _db;

    public AppStateService(SortedLocalDb db) 
    {
        this.AppState = new AppState();
        _db = db;
    }

    public string _CardType = "settings";
    public string CardType
    {
        get => _CardType;
        set
        {
            if (_CardType != value)
            {
                _CardType = value;
                OnPropertyChanged(); // reports this property
            }
        }
    }
    
    public event Action OnChange;
    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged([CallerMemberName] string name = "") =>
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    
    public void NotifyStateChanged() => OnChange?.Invoke();

    //removed other code for brevity but should be unrelated...

    }

}

下面是我的MainPage.xaml.cs:

using MyNamespace.Data;
using System.Globalization;

namespace MyNamespace;

public partial class MainPage : ContentPage
{
    public MainPage(AppStateService AppStateService)
    {
        InitializeComponent();

        this.BindingContext = AppStateService;
    }
}

这是主页面. 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:b="clr-namespace:Microsoft.AspNetCore.Components.WebView.Maui;assembly=Microsoft.AspNetCore.Components.WebView.Maui"
         xmlns:local="clr-namespace:MyNamespace"
         xmlns:data="clr-namespace:MyNamespace.Data"
         BackgroundColor="{DynamicResource PageBackgroundColor}">

<AbsoluteLayout>
    <Label
        x:Name="barcodeResult"
        Text="{Binding CardType}"
        SemanticProperties.HeadingLevel="Level1"
        FontSize="32"
        ZIndex="2"          
      >
    </Label>

    <b:BlazorWebView HostPage="wwwroot/index.html" 
                     AbsoluteLayout.LayoutBounds="0, 0, 1, 1" 
                     AbsoluteLayout.LayoutFlags="All"
                     ZIndex="0">
        <b:BlazorWebView.RootComponents>
            <b:RootComponent Selector="#app" ComponentType="{x:Type local:Main}" />
        </b:BlazorWebView.RootComponents>
    </b:BlazorWebView>
</AbsoluteLayout>

提前感谢!

6uxekuva

6uxekuva1#

是的,数据绑定没有问题,但是我发现你的OnPropertyChanged method使用可能有一些问题。
您需要将CardType名称作为参数添加到OnPropertyChanged method。当它更改时,OnPropertyChanged方法可以注意到该更改。

public string _CardType = "settings";
 public string CardType
    {
        get => _CardType;
        set
        {
            if (_CardType != value)
            {
                _CardType = value;
                OnPropertyChanged("CardType"); 
            }
        }
    }

private void OnPropertyChanged(string propertyName)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

相关问题