未找到绑定属性 - MAUI .NET 8

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

我正在开发 .NET MAUI 项目,遇到以下错误:
[0:] Microsoft.Maui.Controls.Xaml.Diagnostics.BindingDiagnostics: Warning: 'IsAudioEnabled' property not found on 'TTIG02_Controller.Components.ToggleSettingsItem', target property: 'TTIG02_Controller.Components.ToggleSettingsItem.IsToggled'
[0:] Microsoft.Maui.Controls.Xaml.Diagnostics.BindingDiagnostics: Warning: 'IsNotificationEnabled' property not found on 'TTIG02_Controller.Components.ToggleSettingsItem', target property: 'TTIG02_Controller.Components.ToggleSettingsItem.IsToggled'

这是代码的相关部分:

SettingsPage.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="TTIG02_Controller.Views.SettingsPage"
             xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
             xmlns:vm="clr-namespace:TTIG02_Controller.ViewModels"
             xmlns:components="clr-namespace:TTIG02_Controller.Components"
             xmlns:local="clr-namespace:TTIG02_Controller.Views"
             Shell.ForegroundColor="Blue"
             x:DataType="vm:SettingsPageViewModel"
             Title="Impostazioni">

    <ScrollView>
        <VerticalStackLayout>

            <!-- SEZIONE PROFILO -->
            
            <toolkit:AvatarView
                WidthRequest="100"
                HeightRequest="100"
                Margin="0,24,0,0"
                Padding="-2"
                ImageSource="user.png"
                CornerRadius="50"
                BorderColor="Blue"
                StrokeThickness="4" />
            <Label
                Text="{Binding UserFullName}"
                FontSize="24"
                FontAttributes="Bold"
                HorizontalOptions="Center"
                Margin="0,10,0,0" />
            <Label
                Text="{Binding UserEmail}"
                FontSize="16"
                HorizontalOptions="Center"
                Margin="0,4,0,0" />
            
            <!-- SEZIONE IMPOSTAZIONI -->

            <components:ToggleSettingsItem
                Key="audio"
                ToggleChanged="ToggleSettingsItem_ToggleChanged"
                IconSource="icon_audio.svg"
                ItemText="Abilita suoni"
                IsToggled="{Binding IsAudioEnabled}" />

            <components:ToggleSettingsItem
                Key="notification"
                ToggleChanged="ToggleSettingsItem_ToggleChanged"
                IconSource="icon_bell.svg"
                ItemText="Abilita notifiche"
                IsToggled="{Binding IsNotificationEnabled}" />

        </VerticalStackLayout>
    </ScrollView>
    
</ContentPage>

SettingsPage.xaml.cs

public partial class SettingsPage : ContentPage
{
    public SettingsPage()
    {
        InitializeComponent();
        BindingContext = Application.Current!.Handler.MauiContext!.Services.GetRequiredService<SettingsPageViewModel>();
    }

    private void ToggleSettingsItem_ToggleChanged(object sender, ToggledEventArgs e)
    {
        if (sender is not ToggleSettingsItem tsi) return;
        if(string.IsNullOrWhiteSpace(tsi.Key)) return;
        if(BindingContext is not SettingsPageViewModel vm) return;

        Log.Verbose("SettingsPage.ToggleSettingsItem_ToggleChanged: {Key} toggled to {IsToggled}", tsi.Key, e.Value);

        switch(tsi.Key)
        {
            case "audio":
                vm.IsAudioEnabled = e.Value;
                break;
            case "notification":
                vm.IsNotificationEnabled = e.Value;
                break;
            default:
                Log.Warning("SettingsPage.ToggleSettingsItem_ToggleChanged: Unknown key {Key}", tsi.Key);
                break;
        }

    }
}

ToggleSettingsItem.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:TTIG02_Controller.Components"
             x:DataType="local:ToggleSettingsItem"
             x:Class="TTIG02_Controller.Components.ToggleSettingsItem">

    <Grid Margin="12,8,12,8">

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="42" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="42" />
        </Grid.ColumnDefinitions>

        <Border
            Grid.Column="0"
            BackgroundColor="#F0F0F0"
            StrokeShape="RoundRectangle 6"
            StrokeThickness="0"
            Padding="4"
            HorizontalOptions="Center"
            VerticalOptions="Center">

            <Image
                Source="{Binding IconSource}"
                HeightRequest="32"
                WidthRequest="32"
                VerticalOptions="Center"
                HorizontalOptions="Center"
                Aspect="AspectFit" />

        </Border>

        <Label
            Grid.Column="1"
            Text="{Binding ItemText}"
            FontSize="20"
            TextColor="Black"
            VerticalOptions="Center"
            HorizontalOptions="Start"
            Margin="8,0,8,0" />

        <Switch
            x:Name="ToggleSwitch"
            WidthRequest="40"
            HeightRequest="40"
            Grid.Column="2"
            IsToggled="{Binding IsToggled, Mode=TwoWay}"
            HorizontalOptions="End"
            VerticalOptions="Center"
            OnColor="Blue"
            ThumbColor="Gray" />

    </Grid>
    
</ContentView>

ToggleSettingsItem.xaml.cs

public partial class ToggleSettingsItem : ContentView
{
    public string Key
    {
        get => (string)GetValue(KeyProperty);
        set => SetValue(KeyProperty, value);
    }

    public string IconSource
    {
        get => (string)GetValue(IconSourceProperty);
        set => SetValue(IconSourceProperty, value);
    }

    public string ItemText
    {
        get => (string)GetValue(ItemTextProperty);
        set => SetValue(ItemTextProperty, value);
    }

    public bool IsToggled
    {
        get => (bool)GetValue(IsToggledProperty);
        set => SetValue(IsToggledProperty, value);
    }

    public static readonly BindableProperty IconSourceProperty =
        BindableProperty.Create(
            propertyName: nameof(IconSource),
            returnType: typeof(string),
            declaringType: typeof(ToggleSettingsItem),
            defaultValue: string.Empty,
            defaultBindingMode: BindingMode.OneWay
        );

    public static readonly BindableProperty ItemTextProperty =
        BindableProperty.Create(
            propertyName: nameof(ItemText),
            returnType: typeof(string),
            declaringType: typeof(ToggleSettingsItem),
            defaultValue: string.Empty,
            defaultBindingMode: BindingMode.OneWay
        );

    public static readonly BindableProperty IsToggledProperty =
        BindableProperty.Create(
            propertyName: nameof(IsToggled),
            returnType: typeof(bool),
            declaringType: typeof(ToggleSettingsItem),
            defaultValue: false,
            defaultBindingMode: BindingMode.TwoWay
        );

    public static readonly BindableProperty KeyProperty =
        BindableProperty.Create(
            propertyName: nameof(Key),
            returnType: typeof(string),
            declaringType: typeof(ToggleSettingsItem),
            defaultValue: string.Empty,
            defaultBindingMode: BindingMode.OneWay
        );

    public event EventHandler<ToggledEventArgs>? ToggleChanged;

    public ToggleSettingsItem()
    {
        InitializeComponent();
        ToggleSwitch.Toggled += OnToggleSwitchToggled;
    }

    private void OnToggleSwitchToggled(object? sender, ToggledEventArgs e)
    {
        Log.Verbose("ToggleSettingsItem.OnToggleSwitchToggled: {ItemText} toggled to {IsToggled}", ItemText, IsToggled);
        ToggleChanged?.Invoke(this, e);
    }
}

SettingsPageViewModel.cs

namespace TTIG02_Controller.ViewModels
{
    public class SettingsPageViewModel : INotifyPropertyChanged
    {
        private bool _isAudioEnabled;
        public bool IsAudioEnabled
        {
            get => _isAudioEnabled;
            set
            {
                if (_isAudioEnabled != value)
                {
                    _isAudioEnabled = value;
                    OnPropertyChanged(nameof(IsAudioEnabled));
                }
            }
        }

        private bool _isNotificationEnabled;
        public bool IsNotificationEnabled
        {
            get => _isNotificationEnabled;
            set
            {
                if (_isNotificationEnabled != value)
                {
                    _isNotificationEnabled = value;
                    OnPropertyChanged(nameof(IsNotificationEnabled));
                }
            }
        }

        public event PropertyChangedEventHandler? PropertyChanged;

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

以下关于我已经尝试过的类似帖子的建议:

  • 删除
    x:DataType
  • 设置
    xmlns:local
  • BindingContext = this;
     中删除 
    ToggleSettingsItem
  • IsToggled="{Binding Source={x:Reference SettingsPage}, Path=BindingContext.IsNotificationEnabled}"

有人可以帮我找出导致此问题的原因吗?
谢谢!

c# .net xaml binding maui
1个回答
0
投票

首先,这些是警告而不是错误

如果您在

ToggleSettingsItem.xaml.cs
中设置 BindingContext = this

这意味着ToggleSettingsItem的所有绑定都来自其自身,包括您在SettingsPage.xaml中定义的那些。例如

{Binding IsAudioEnabled}

但是,

IsAudioEnabled
是您的SettingsPageViewModel的属性。自警告以来,由于绑定需要 ToggleSettingsItem

上的属性

如果您想保留

BindingContext = this
ToggleSettingsItem。然后您需要在 SettingsPage.xaml

中显式引用您的绑定

Step1:为您定义一个 x:Name SettingsPage.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="TTIG02_Controller.Views.SettingsPage"
             x:Name="settingPage"

第 2 步:使用 x:Reference

显式引用您的绑定
<components:ToggleSettingsItem
                Key="audio"
                ToggleChanged="ToggleSettingsItem_ToggleChanged"
                IconSource="icon_audio.svg"
                ItemText="Abilita suoni"
                IsToggled="{Binding Source={x:Reference settingPage},Path= BindingContext.IsAudioEnabled}" />
© www.soinside.com 2019 - 2024. All rights reserved.