XAML CollectionView绑定无法正常工作

siv3szwd  于 2023-11-14  发布在  其他
关注(0)|答案(2)|浏览(111)

在我的.Net MAUI应用程序中,我有一个viewmodel VideoChatPageModel,它包含以下可观察属性:

[ObservableProperty]
    private LanguageViewModel _selectedLanguage;

    [ObservableProperty]
    private List<LanguageViewModel> _languages = new()
    {
        new LanguageViewModel { LanguageName = "English", FlagImage = "flag_united_kingdom.png", LanguageCode = "en" },
        new LanguageViewModel { LanguageName = "Spanish", FlagImage = "flag_spain.png", LanguageCode = "es" },
        new LanguageViewModel { LanguageName = "French", FlagImage = "flag_france.png", LanguageCode = "fr" }
    };

字符串
下面是一个示例:

public class LanguageViewModel
{
    public string LanguageName { get; set; }
    public string LanguageCode { get;set; }
    public string FlagImage { get; set; }
}


我在页面上有以下CollectionView:

<CollectionView 
                    Margin="5,5,5,15"
                    ItemSizingStrategy="MeasureAllItems"
                    ItemsSource="{Binding Languages}"
                    SelectedItem="{Binding SelectedLanguage, Mode=TwoWay}"
                    SelectionMode="Single">
                <CollectionView.ItemsLayout>
                    <GridItemsLayout Orientation="Vertical" />
                </CollectionView.ItemsLayout>
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <ContentView Padding="5" >
                            <Grid ColumnDefinitions="*,3*">
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="40" />
                                </Grid.RowDefinitions>
                                <Image Source="{Binding FlagImage}" Grid.Column="0" HorizontalOptions="Start" />
                                <Label Text="{Binding LanguageName}" Grid.Column="1" HorizontalOptions="Start" />
                            </Grid>
                        </ContentView>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>


由于某些原因,它无法编译:
错误XFC0045绑定:在“Features.VideoChat.VideoChatPageModel”上未找到属性“FlagImage”。
很明显,它不是在WebageViewModel类中查找属性,而是在VideoChatPageModel中查找,VideoChatPageModel是整个页面的绑定上下文:

public VideoChatPage(VideoChatPageModel pageModel)
{
    InitializeComponent();
    BindingContext = pageModel;
}


但是为什么会这样呢?如果我用下面的选择器替换CollectionView,它就可以工作了:

<Picker ItemsSource="{Binding Languages}" SelectedItem="{Binding SelectedLanguage}" ItemDisplayBinding="{Binding LanguageName}">                    
            </Picker>

nqwrtyyt

nqwrtyyt1#

为了进一步澄清我关于LanguageViewModel可以被CultureInfo替换的评论,你可以通过在构造函数中传递一个locale名称来初始化它,它会自动填充其他有用的属性,如NativeNameEnglishNameLCIDTwoLetterISOLanguageName等等。你可以使用任何这些参数来生成一个标志文件名。
下面是一个工作示例:

// MauiProgram.cs ...
builder.Services.AddTransient<MainPage>();
builder.Services.AddTransient<MainViewModel>();
// MainViewModel.cs ...
public partial class MainViewModel : ObservableObject
{
    [ObservableProperty]
    private CultureInfo _selectedLanguage;

    [ObservableProperty]
    private List<CultureInfo> _languages = new List<CultureInfo>()
    {
        new CultureInfo("en-US"),
        new CultureInfo("es-ES"),
        new CultureInfo("fr-FR")
    };
}
// MainPage.xaml.cs
public partial class MainPage : ContentPage
{
    public MainPage(MainViewModel VM)
    {
        InitializeComponent();
        BindingContext = VM;
    }
}
<!-- MainPage.xaml ... -->
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:g="clr-namespace:System.Globalization;assembly=mscorlib"
             x:Class="maui_language_picker.MainPage">
    <CollectionView ItemSizingStrategy="MeasureAllItems"
                ItemsSource="{Binding Languages}"
                SelectedItem="{Binding SelectedLanguage, Mode=TwoWay}"
                SelectionMode="Single">
        <CollectionView.ItemsLayout>
            <GridItemsLayout Orientation="Vertical" />
        </CollectionView.ItemsLayout>
        <CollectionView.ItemTemplate>
            <DataTemplate x:DataType="g:CultureInfo">
                <ContentView Padding="5" >
                    <Grid ColumnDefinitions="*,3*">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="40" />
                        </Grid.RowDefinitions>
                        <Image Source="{Binding LCID, StringFormat='flag_{0}.png'}" Grid.Column="0" HorizontalOptions="Start" />
                        <Label Text="{Binding NativeName}" Grid.Column="1" HorizontalOptions="Start" />
                    </Grid>
                </ContentView>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</ContentPage>

您可以将标记资源创建为:

  • Resources/Images/flag_1033.svg//zh-CN
  • Resources/Images/flag_3082.svg// es-ES
  • Resources/Images/flag_1036.svg// fr-FR

您可以通过在csproj中设置BaseSize来保守地限制标志分辨率,例如。

<!-- Images -->
<MauiImage Update="Resources\Images\flag_*.svg" BaseSize="60,40" />


参考文献:

thtygnil

thtygnil2#

您需要将x:DataType添加到DataTemplate,以便它知道其BindingContext的类型

相关问题