如何在 MAUI 应用程序中正确设置 XAML 绑定

问题描述 投票:0回答:1

我用一个 XAML 页面编写了一个简单的字典应用程序,然后我决定将条目和翻译放入带有自己的 ViewmModel 的单独视图中,乐趣就开始了。

基本上我设法让一切正常工作,但它只是向我显示了这些烦人的 XAML 绑定错误,我不知道为什么,AI 在这方面变得愚蠢,非常感谢帮助!

EntryModel 具有属性

Header
Subheader

TranslationModel 有自己的属性

错误看起来像这样:

Severity    Count   Data Context    Binding Path    Target  Target Type Description File    Line    Project

Error   50  EntryViewModel  Header  Label.Text  String  'Header' property not found on 'dosham.ViewModels.EntryViewModel', target property: 'Microsoft.Maui.Controls.Label.Text'    C:\Users\x.dr\source\repos\movsar\chldr\src\chldr_maui\Views\EntryView.xaml 11  dosham

Error   50  EntryViewModel  Subheader   Label.Text  String  'Subheader' property not found on 'dosham.ViewModels.EntryViewModel', target property: 'Microsoft.Maui.Controls.Label.Text' C:\Users\x.dr\source\repos\movsar\chldr\src\chldr_maui\Views\EntryView.xaml 14  dosham

Error   50  EntryViewModel  Translations    StackLayout.ItemsSource IEnumerable 'Translations' property not found on 'dosham.ViewModels.EntryViewModel', target property: 'Microsoft.Maui.Controls.StackLayout.ItemsSource' C:\Users\x.dr\source\repos\movsar\chldr\src\chldr_maui\Views\EntryView.xaml 18  dosham

Error   50  EntryViewModel  .   EntryView.Entry EntryModel  'dosham.ViewModels.EntryViewModel' cannot be converted to type 'chldr_data.DatabaseObjects.Models.EntryModel'   C:\Users\x.dr\source\repos\movsar\chldr\src\chldr_maui\Pages\MainPage.xaml  24  dosham

我看到它说它在我的 ViewModel 上找不到标题和子标题,但它不应该在 ViewModel 上寻找它们,而应该在 ViewModel 的输入和翻译模型上寻找它们。我如何在不破坏当前正在运行的绑定的情况下判断这一点?

另外,如果您对代码组织有更好的建议 - 欢迎您提出建议。

这是代码:

主页

-- 查看

<?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:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:vm="clr-namespace:dosham.ViewModels"
             xmlns:views="clr-namespace:dosham.Views"
             x:Class="dosham.Pages.MainPage">

    <Grid Padding="10">
        <!-- Define the rows -->
        <Grid.RowDefinitions>
            <!-- For CollectionView, takes remaining space -->
            <RowDefinition Height="*"/>
            <!-- For Search Box -->
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <!-- Collection View for Entries -->
        <CollectionView x:Name="EntriesCollectionView" Grid.Row="0"
                        ItemsSource="{Binding FilteredEntries}">
            <CollectionView.ItemTemplate>
                <DataTemplate>

                    <views:EntryView Entry="{Binding .}"></views:EntryView>
                    
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>

        <!-- Search Box -->
        <Entry x:Name="SearchBox" Grid.Row="1"
         Text="{Binding SearchText, Mode=TwoWay}" 
         Placeholder="Начните писать..." 
         Margin="0,0,0,10" />
    </Grid>
</ContentPage> 

-- 代码隐藏

 public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            BindingContext = App.Services.GetRequiredService<MainPageViewModel>();
        }
    }

-- 视图模型

public class MainPageViewModel : ReactiveObject
{
    public IEnumerable<EntryModel> FilteredEntries
    {
        get => _filteredEntries;
        set => this.RaiseAndSetIfChanged(ref _filteredEntries, value);
    }
....

入口视图

-- 查看

<?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:views="clr-namespace:dosham.Views"
             x:Class="dosham.Views.EntryView">
    
    <StackLayout Orientation="Vertical">
        <Frame CornerRadius="10" Margin="5" Padding="10" BorderColor="#CACCaa" BackgroundColor="#f9F9F9">
            <StackLayout Orientation="Vertical" Spacing="5">
                <!-- Entry Content -->
                <Label Text="{Binding Header}" FontSize="Medium" FontAttributes="Bold" TextColor="#000" />

                <!-- Source Name -->
                <Label Text="{Binding Subheader}" FontSize="Micro" TextColor="#cba" />


                <!-- Translation views -->
                <StackLayout BindableLayout.ItemsSource="{Binding Translations}">
                    <BindableLayout.ItemTemplate>
                        <DataTemplate>
                            <views:TranslationView Translation="{Binding .}" />
                        </DataTemplate>
                    </BindableLayout.ItemTemplate>
                </StackLayout>
            </StackLayout>
        </Frame>
    </StackLayout>

</ContentView>

-- 代码隐藏

public partial class EntryView : ContentView
{
    private EntryViewModel _viewModel;

    public static readonly BindableProperty EntryProperty =
         BindableProperty.Create(nameof(_viewModel.Entry), typeof(EntryModel), typeof(EntryView));

    public EntryView()
    {
        _viewModel = App.Services.GetRequiredService<EntryViewModel>();
        BindingContext = _viewModel;
        InitializeComponent();
    }
}

-- 视图模型

 public class EntryViewModel : ViewModelBase
 {
     #region Properties, Actions and Constructors
     public EntryModel Entry { get; set; }
     ...
 }

翻译查看

-- 查看

<?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:dosham.Views"
             x:Class="dosham.Views.TranslationView">

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>

        <!-- Language Code Label -->
        <Label Grid.Column="0"
                  Text="{Binding LanguageCode, StringFormat='{0}:'}" 
                  FontSize="Small" 
                  FontAttributes="Italic" 
                  TextColor="#AA6666" />

        <!-- Content Label -->
        <Label Grid.Column="1"
                  Text="{Binding Content, StringFormat=' {0}'}" 
                  FontSize="Small" 
                  TextColor="#666666" />
    </Grid>

</ContentView>

-- 代码隐藏

public partial class TranslationView : ContentView
{
    private readonly TranslationViewModel _viewModel;

    public static readonly BindableProperty TranslationProperty =
     BindableProperty.Create(nameof(_viewModel.Translation), typeof(TranslationModel), typeof(TranslationView));

    public TranslationView()
    {
        _viewModel = App.Services.GetRequiredService<TranslationViewModel>();
        BindingContext = _viewModel;

        InitializeComponent();
    }
}

-- 视图模型

public class TranslationViewModel : ViewModelBase
{
    public TranslationViewModel(ContentStore contentStore, UserStore userStore) : base(contentStore, userStore)
    { }
    public TranslationModel Translation { get; set; }
....
}

这是视觉效果:

c# xaml data-binding maui reactiveui
1个回答
0
投票

我相信你需要类似...

<Label Text="{Binding Source={RelativeSource AncestorType={x:Type model:EntryViewModel}}, Path=Header}" FontSize="Medium" FontAttributes="Bold" TextColor="#000" />

注意:我现在无法对此进行测试,因此无法验证我的答案的准确性。

© www.soinside.com 2019 - 2024. All rights reserved.