[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}"
有人可以帮我找出导致此问题的原因吗?
谢谢!
首先,这些是警告而不是错误。
如果您在
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}" />