XAML 无法对自定义控件进行数据绑定

ttp71kqs  于 2022-12-07  发布在  其他
关注(0)|答案(2)|浏览(138)

我创建了一个带有自定义属性的自定义组件。问题是当我试图使用它将某些内容绑定到组件时,它将无法编译并引发错误。
错误:

[XFC0009] No property, BindableProperty, or event found for "Label", or mismatching type between value and property.

组件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:viewmodel="clr-namespace:TestProject.Components"
             x:DataType="viewmodel:Tile"
             x:Class="TestProject.Components.Tile">

    <Frame CornerRadius="10"
           WidthRequest="300"
           HeightRequest="150">
        <Frame.GestureRecognizers>
            <TapGestureRecognizer Tapped="TileClicked"/>
        </Frame.GestureRecognizers>
        <StackLayout x:Name="SL_Content"
                     HorizontalOptions="Start"
                     VerticalOptions="Start">
            <Label Text="{Binding Label}" 
                   FontSize="{Binding Size}" 
                   FontAttributes="Bold"/>
            <Image Source="{Binding Icon}"
                   HorizontalOptions="Start"
                   WidthRequest="50"
                   HeightRequest="0"
                   Margin="0,10,0,0"
                   x:Name="I_Img"/>
        </StackLayout>
    </Frame>
</ContentView>

不可绑定的标签属性代码:

private static readonly BindableProperty LabelProperty = BindableProperty.Create(
        propertyName: nameof(Label),
        returnType: typeof(string),
        defaultValue: string.Empty,
        declaringType: typeof(Tile),
        defaultBindingMode: BindingMode.OneWay);

public string Label
    {
        get => (string)GetValue(LabelProperty);
        set => SetValue(LabelProperty, value);
    }

施工单位:

public Tile()
{
    BindingContext = this;
    InitializeComponent();
}

控件的用法:

<?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:components="clr-namespace:TestProject.Components"
                    xmlns:model="clr-namespace:TestProject.Model"
                    xmlns:viewmodel="clr-namespace:TestProject.ViewModel"
                    x:DataType="viewmodel:ScannedItemViewModel"
                    x:Class="TestProject.Pages.Popups.CodeDetected">
  
    <CollectionView ItemsSource="{Binding _scannedItems}">
        <CollectionView.ItemTemplate>
            <DataTemplate x:DataType="model:ScannedItem">
                <SwipeView>
                    <SwipeView.RightItems>
                        <SwipeItem Text="Delete"
                                   Invoked="SwipeItem_OnDelete"/>
                    </SwipeView.RightItems>
                    <HorizontalStackLayout HeightRequest="40">
                        <Label VerticalOptions="Center" HorizontalOptions="Start" WidthRequest="120"
                               Padding="15,0,0,0" FontSize="16" Text="{Binding _num}" />
                        <Label VerticalOptions="Center" HorizontalOptions="Start" FontSize="16"
                               Text="{Binding _serial}" />

无法像这样将某些内容绑定到标签,否则将引发错误

一个

bis0qfac

bis0qfac1#

Usually, it makes a lot of sense to just tell your View that it needs to look for the bindings in itself:

<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:viewmodel="clr-namespace:TestProject.Components"
         x:DataType="viewmodel:Tile"
         x:Name"this"
         x:Class="TestProject.Components.Tile">

And then change the binding like so:

<Label Text="{Binding Label}" 
                   FontSize="{Binding Size, Source={x:Reference this}}" 
                   FontAttributes="Bold"/>
            <Image Source="{Binding Icon, Source={x:Reference this}}"
                   HorizontalOptions="Start"
                   WidthRequest="50"
                   HeightRequest="0"
                   Margin="0,10,0,0"
                   x:Name="I_Img"/>

Also, BindingContext this in a custom control is always a mistake it messes with your controls VM assignment when you use it in views so change your constructor to

public Tile()
{
  InitializeComponent();
}

Good luck!

x6h2sr28

x6h2sr282#

只需要将private改为public即可,例如:

public static readonly BindableProperty LabelProperty = BindableProperty.Create(
    propertyName: nameof(Label),
    returnType: typeof(string),
    defaultValue: string.Empty,
    declaringType: typeof(Tile),
    defaultBindingMode: BindingMode.OneWay);

我曾经遇到过这个问题,而且在公文中,也是公开的。

相关问题