C# 设置BindableProperty时未触发OnPropertyChanged
我在Xamarin.Forms中的自定义C# 设置BindableProperty时未触发OnPropertyChanged,c#,xamarin,xamarin.forms,C#,Xamarin,Xamarin.forms,我在Xamarin.Forms中的自定义ContentView中设置BindablePropertyIconName时遇到问题。它永远不会被设置并且保持为空。除了IconName之外,对每个属性都执行OnPropertyChanged方法。当我将类型从enum更改为字符串时,它会按预期工作。我错过了什么 需要使用OnPropertyChanged方法,否则将设置非属性并保持其默认值 <?xml version="1.0" encoding="UTF-8&quo
ContentView
中设置BindableProperty
IconName
时遇到问题。它永远不会被设置并且保持为空。除了IconName
之外,对每个属性都执行OnPropertyChanged
方法。当我将类型从enum更改为字符串时,它会按预期工作。我错过了什么
需要使用OnPropertyChanged
方法,否则将设置非属性并保持其默认值
<?xml version="1.0" encoding="UTF-8" ?>
<ContentView
x:Class="Peripass.Mobile.Framework.UIControls.PeripassIcon"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<ContentView.Resources>
</ContentView.Resources>
<ContentView.Content>
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<Image>
<Image.Source>
<FontImageSource x:Name="_icon" Glyph="" Color="Black" Size="20" FontFamily="{OnPlatform Android=PeripassIcon.ttf#}" />
</Image.Source>
</Image>
</StackLayout>
</ContentView.Content>
</ContentView>
您遇到的问题与以下事实有关:
OnPropertyChanged
仅在属性值更改时触发(设置它是不够的!)
在代码中,您将默认值IconName
设置为IconType.NuclearExplosion
。稍后,当您调用所设置的控件时
它将IconName
设置为默认值,再次。。。因此它的值实际上不会改变,因此不会触发OnPropertyChanged
警告
话虽如此,我必须提到,您将在BindableProperties和视图中的对应项之间使用绑定的“正常”。例如,您可以将ContentView中FontImageSource中的Color属性值绑定到BindableProperty IconColor。有关详细信息,请参阅。@Tijl.Reynhout,我很高兴它对您有所帮助。我用警告扩展了答案。请看一看,让我知道它是否对您有帮助…您的意思是像我的FontImageSource Color=“{Binding IconColor}”上这样,因为出于某种原因,这不起作用…如果您对如何做有疑问,请发布另一个问题,我将很乐意看一看:)我创建了关于此主题的另一个问题:)
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace Peripass.Mobile.Framework.UIControls
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class PeripassIcon : ContentView
{
public static readonly BindableProperty IconSizeProperty = BindableProperty.Create(nameof(IconSize), typeof(double), typeof(PeripassIcon), 26.0);
public static readonly BindableProperty IconColorProperty = BindableProperty.Create(nameof(IconColor), typeof(Color), typeof(PeripassIcon), Color.White);
public static readonly BindableProperty IconNameProperty = BindableProperty.Create(nameof(IconName), typeof(IconType), typeof(PeripassIcon), IconType.NuclearExplosion);
public PeripassIcon()
{
InitializeComponent();
}
public IconType IconName
{
get => (IconType)GetValue(IconNameProperty);
set => SetValue(IconNameProperty, value);
}
public double IconSize
{
get => (double)GetValue(IconSizeProperty);
set => SetValue(IconSizeProperty, value);
}
public Color IconColor
{
get => (Color)GetValue(IconColorProperty);
set => SetValue(IconColorProperty, value);
}
protected override void OnPropertyChanged(string propertyName = null)
{
base.OnPropertyChanged(propertyName);
if (propertyName == IconNameProperty.PropertyName) {
_icon.Glyph = $"&#x{(int)IconName:X4};";
}
if (propertyName == IconColorProperty.PropertyName) {
_icon.Color = IconColor;
}
if (propertyName == IconSizeProperty.PropertyName) {
_icon.Size = IconSize;
}
}
}
}
<StackLayout Grid.Row="1" Grid.Column="0">
<uiControls:PeripassIcon IconName="NuclearExplosion" IconColor="#EE4022" IconSize="85.5"/>
</StackLayout>