我用一个 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; }
....
}
我相信你需要类似...
<Label Text="{Binding Source={RelativeSource AncestorType={x:Type model:EntryViewModel}}, Path=Header}" FontSize="Medium" FontAttributes="Bold" TextColor="#000" />
注意:我现在无法对此进行测试,因此无法验证我的答案的准确性。