我正在尝试创建一个内容视图,我想在其中封装尽可能多的逻辑,以保持我的代码DRY,但我不确定我是否做错了什么,或者只是限制了可绑定属性及其访问器如何触发通知更改事件。不管怎样,这是我的例子
ContentView.xaml.cs
public static readonly BindableProperty TotalItemsProperty = BindableProperty.Create(nameof(TotalItems), typeof(int), typeof(SortingPageView),
defaultBindingMode: BindingMode.TwoWay);
public int TotalItems
{
get => (int)GetValue(TotalItemsProperty);
set
{
SetValue(TotalItemsProperty, value);
OnPropertyChanged(nameof(CurrentPageText));
}
}
public string CurrentPageText { get => $" / {TotalPages}"; }
ContentView.xaml
<Grid ColumnDefinitions="50, auto, 50" Grid.Column="1" HorizontalOptions="End">
<Image Grid.Column="0" IsVisible="{Binding CanGoBack}" Source="left_arrow.png" HeightRequest="30">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="GoBack"/>
</Image.GestureRecognizers>
</Image>
<HorizontalStackLayout Margin="10, 0" Grid.Column="1">
<Entry FontSize="20" Text="{Binding CurrentPage}"/>
<Label FontSize="20" Text="{Binding CurrentPageText}" VerticalOptions="Center"/>
</HorizontalStackLayout>
<Image Grid.Column="2" Source="right_arrow.png" HeightRequest="30">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="GoNext"/>
</Image.GestureRecognizers>
</Image>
</Grid>
ViewModel.cs
public async Task LoadJobs(bool resetCurrentPage = false)
{
this.IsLoading = true;
try
{
if(resetCurrentPage)
{
this.CurrentPage = 1;
}
var jobs = await this.jobsService.GetJobs(Filter, Pagination);
this.InitialJobs = jobs.Items.Select(x => new JobDto(x)).ToList();
this.TotalItems = jobs.TotalItems; -- only this line is importent
MainThread.BeginInvokeOnMainThread(() =>
{
this.Jobs.Clear();
this.Jobs.AddRange(jobs.Items);
});
}
catch(Exception ex)
{
}
finally
{
this.IsLoading = false;
}
}
请注意TotalItems属性并不显示在实际的ContentView中。xaml仅用于计算基于它的其他属性,但它的setter永远不会被调用(只有当TotalItems属性在xaml中时才有断点),所以我在这里做错了什么吗?
PS ContentView.xaml.cs构造函数
public SortingPageView()
{
InitializeComponent();
Content.BindingContext = this;
}
更新
视图模型并不是针对contentView的,而是针对我想要显示内容视图的视图。
据我所知,我需要在内容视图中定义一个BindableProperty,其中包含accessero属性,而在视图模型中,我需要传递totalItems属性。有点像vue,棱角分明
2条答案
按热度按时间mwkjh3gx1#
创建ContentViews时,请将其视为ContentPage中的内容。因此它应该依赖于ContentPage的ViewModel,而不是拥有自己的ViewModel或绑定到自身。我认为,如果你的ContentView需要自己的视图模型,你就在某个地方犯了一个设计错误。但这是个见仁见智的问题。
因此,请删除指向此的BindingContext,并将控件所需的所有逻辑从控件所属的View中移到ViewModel中的数据和属性上。你没有给我们一个完整的代码结构,所以我不能告诉你我认为它应该是什么。如果你想使用bindnig并指向你自己的代码,你可以使用引用,比如
{Binding MessageText, Source={x:Reference ThisView}}
,其中ThisView是你拥有的Control的x:Name
。bprjcwpo2#
好了,我认为问题要么出在视图模型中绑定的方式上,要么出在conentView.xaml中没有添加
在contentView in my case网格中的根元素上
您可以看到这是实际的内容视图,与我读到的应该绑定到内容视图的绑定上下文相反,我仍然这样做了,并且它按预期的ContentView.xaml.cs工作
好了,现在我只是粘贴一些代码,作为其他人(或我未来的自己)的模板:D
ContentView.xaml.cs
ContentView.xaml
JobsView.xaml
JobsViewModel.cs
由于ContentView.xaml.cs中的CurrentPageProperty具有BindingMode = TwoWay,因此在viewModel中,我侦听CurrentPage中的更改以加载相应的项。
请注意,转到下一页的逻辑在ContentView中通过属性CanGoNext和CanGoBack以及方法(绑定到点击事件)GoNext和GoBack进行验证和触发