XAML MAUI CollectionView中的绑定字符串问题

pes8fvy9  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(116)

我创建了一个名为SectionTitle的.net MAUI组件,它有两个属性:一个用于背景颜色,一个用于标签。

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

    <Grid ColumnDefinitions="3*,2*">
        <Grid ColumnDefinitions="Auto,*">
            <Border
                x:Name="Bordo"
                Grid.Column="0"
                Padding="5,10,20,10"
                Background="{Binding BGColor}"
                StrokeShape="RoundRectangle 0,10,0,10">
                <Label
                    x:Name="Lbl"
                    Grid.Column="0"
                    Text="{Binding LabelText}" />
            </Border>
        </Grid>
    </Grid>
</ContentView>

字符串
相应的C#代码如下:

namespace mater.Components;

public partial class SectionTitle : ContentView
{
    public static readonly BindableProperty BGColorProperty = BindableProperty.Create(
            nameof(BGColor), typeof(Brush), typeof(SectionTitle), default(Brush));

    public static readonly BindableProperty LabelTextProperty = BindableProperty.Create(
        nameof(LabelText), typeof(string), typeof(SectionTitle), "");

    public Brush BGColor
    {
        get { return (Brush)GetValue(BGColorProperty); }
        set { SetValue(BGColorProperty, value); }
    }

    public string LabelText
    {
        get { return (string)GetValue(LabelTextProperty); }
        set { SetValue(LabelTextProperty, value); }
    }

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


当在CollectionView中使用它时,当直接使用模型的Label属性时,绑定工作,但当数据通过SectionTitle组件时,它不工作。为LabelText设置静态值可以工作。

<?xml version="1.0" encoding="UTF-8" ?>
<ContentPage
    x:Class="mater.Views.HygienePage"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:c="clr-namespace:mater.Components"
    xmlns:local="clr-namespace:mater"
    xmlns:models="clr-namespace:mater.Models"
    xmlns:vm="clr-namespace:mater.ViewModels"
    x:DataType="vm:HygieneViewModel">
    <ScrollView>
        <StackLayout Margin="0,10,0,0">
            <CollectionView
                Margin="20,10,20,10"
                ItemsSource="{Binding Cards}"
                SelectionChanged="CollectionView_SelectionChanged"
                SelectionMode="Single">
                <CollectionView.ItemsLayout>
                    <GridItemsLayout
                        HorizontalItemSpacing="20"
                        Orientation="Vertical"
                        Span="2"
                        VerticalItemSpacing="20" />
                </CollectionView.ItemsLayout>
                <CollectionView.ItemTemplate>
                    <DataTemplate x:DataType="models:CardItem">
                        <StackLayout Margin="0,0,0,10" Background="{StaticResource LightGrey}">
                            <Grid ColumnDefinitions="Auto,*">
                                <Border
                                    Grid.Column="0"
                                    Margin="0,10,0,0"
                                    Padding="5,10,20,10"
                                    Background="{StaticResource Coral}"
                                    StrokeShape="RoundRectangle 0,10,0,10">
                                    <Label Text="{Binding Label}" />
                                </Border>
                                <Grid Grid.Column="1" />
                            </Grid>
<!-- Here if I put LabelText="ASD" it works, with the binding it doesn't work, the binding 3 lines before works -->
                            <c:SectionTitle BGColor="{StaticResource Coral}" LabelText="{Binding Label}" />
                            <Image HeightRequest="150" Source="{Binding Icon}" />
                        </StackLayout>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
        </StackLayout>
    </ScrollView>

</ContentPage>


为了完整起见,我还添加了相应的C#代码

using mater.ViewModels;
using mater.Models;
using mater.Resources.Strings;

namespace mater.Views;

public partial class HygienePage : ContentPage
{
    public List<CardItem> Cards = new()
    {
        new CardItem
        {
            Icon="rischi_micro.png",
            Label=AppStrings.SicRischi
        },
        new CardItem
        {
            Icon="da_evitare.png",
            Label=AppStrings.SicEvitare
        },
        new CardItem
        {
            Icon="acquisto.png",
            Label=AppStrings.SicLavaggio
        },
        new CardItem
        {
            Icon="cottura.png",
            Label=AppStrings.SicCottura
        },
        new CardItem
        {
            Icon="contaminazioni.png",
            Label=AppStrings.SicContaminazioni
        },
    };
    public HygieneViewModel vm { get; set; }
    public HygienePage()
    {
        InitializeComponent();
        vm = new HygieneViewModel();
        vm.Cards = Cards;
        BindingContext = vm;
    }

    async void CollectionView_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (e.CurrentSelection.Count > 0)
        {
            CardItem selectedCard = (CardItem)e.CurrentSelection[0];

            ((CollectionView)sender).SelectedItem = null;
            switch (selectedCard.Label)
            {
                case var value when value == AppStrings.SicRischi:
                    await Shell.Current.GoToAsync("rischimicropage");
                    break;

                case var value when value == AppStrings.SicEvitare:
                    await Shell.Current.GoToAsync("evitarepage");
                    break;

                case var value when value == AppStrings.SicLavaggio:
                    await Shell.Current.GoToAsync("lavaggiopage");
                    break;

                case var value when value == AppStrings.SicCottura:
                    await Shell.Current.GoToAsync("cotturapage");
                    break;

                case var value when value == AppStrings.SicContaminazioni:
                    await Shell.Current.GoToAsync("contaminazionipage");
                    break;

                default:
                    break;
            }

        }
}
}


CardItem模型:

using System;
namespace mater.Models;

public class CardItem
{
    public ImageSource Icon { get; set; }
    public string Label { get; set; }
    public bool isVisible { get; set; } = true;
}


viewModel:

using System;
using CommunityToolkit.Mvvm.ComponentModel;
using mater.Models;

namespace mater.ViewModels;

public partial class HygieneViewModel: ObservableObject
{
    [ObservableProperty]
    private List<CardItem> cards;

}


你知道我在装订上做错了什么吗?

1aaf6o9v

1aaf6o9v1#

因此,正如@Jason在评论中强调的那样,问题在于控件中BindingContext=this的使用。
我从C#中的构造函数中删除了

BindingContext = this;

字符串
向控件添加了x:Name,绑定Source更新如下:

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

    <Grid ColumnDefinitions="3*,2*">
        <Grid ColumnDefinitions="Auto,*">
            <Border
                x:Name="Bordo"
                Grid.Column="0"
                Padding="5,10,20,10"
                Background="{Binding Source={x:Reference self}, Path=BGColor}"
                StrokeShape="RoundRectangle 0,10,0,10">
                <Label
                    x:Name="Lbl"
                    Grid.Column="0"
                    Text="{Binding Source={x:Reference self}, Path=LabelText}" />
            </Border>
        </Grid>
    </Grid>
</ContentView>


现在一切正常

相关问题