Xamarin.Forms 如何更新CarouselView内部绑定的Label文本
如何实现CarouselView内部Label的文本更新
我定义了如下Label控件:
<Label x:Name="QuestionText" FontSize="62" Text="{Binding question}" HorizontalTextAlignment="Center" Padding="0,20,0,0" />
该Label放在CarouselView控件内部,CarouselView完整代码如下:
<CarouselView x:Name="Questions" HeightRequest="475"> <CarouselView.ItemTemplate> <DataTemplate> <StackLayout HorizontalOptions="Center" Padding="10"> <Label x:Name="QuestionText" FontSize="62" Text="{Binding question}" HorizontalTextAlignment="Center" Padding="0,20,0,0" /> </StackLayout> </DataTemplate> </CarouselView.ItemTemplate> </CarouselView>
我重写了OnAppearing方法给CarouselView填充数据,逻辑如下:
protected override async void OnAppearing() { base.OnAppearing(); questions = await webService.GetTaskQuestions(taskcategory); List<QuestionsClass> currentPage = new List<QuestionsClass>(); currentPage.Add(questions[currentPageIndex]); Questions.ItemsSource = currentPage; }
我尝试用下面的逻辑更新Label的显示文本:
questions[currentPageIndex].question = questions[currentPageIndex].question.Replace("_", questions[currentPageIndex].answer);
甚至切到主线程执行修改操作:
Device.BeginInvokeOnMainThread(() => { questions[currentPageIndex].question = questions[currentPageIndex].question.Replace("_", questions[currentPageIndex].answer); });
但Label始终没有刷新,实体类定义如下:
public class QuestionsClass { public string question { get; set; } public string answer { get; set; } }
首次尝试修复(未生效)
我尝试让实体类继承INotifyPropertyChanged接口,修改后的类定义如下:
public class QuestionsClass : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public string question { get; set; } public string actualQuestion { get { return question; } set { question = value; OnPropertyChanged(); } } public string answer { get; set; } protected void OnPropertyChanged([CallerMemberName] string quetion = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(question)); } }
同时修改了Label的绑定配置:
<Label FontSize="62" Text="{Binding actualQuestion}" HorizontalTextAlignment="Center" Padding="0,20,0,0" />
还是用原来的逻辑修改question属性,依然没有生效。
最终修复方案(已生效)
之前的INotifyPropertyChanged实现存在错误,修正后的实体类如下,修改后功能正常运行:
public class QuestionsClass : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private string _question; public string question { get { return _question; } set { _question = value; NotifyPropertyChanged("question"); } } public string answer { get; set; } private void NotifyPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } }
问题原因与实现说明
这个问题的核心是XAML数据绑定依赖属性变更通知才能刷新UI:
- 最初的
QuestionsClass是普通POCO类,属性值变更时不会主动通知UI,所以修改后Label感知不到变化 - 第一次实现INotifyPropertyChanged时有两个错误:
- 直接修改了没有通知逻辑的自动属性
question,没有触发actualQuestion的setter,自然不会触发变更通知 OnPropertyChanged方法里错误地把question变量的值当成了属性名传入,导致UI绑定匹配不到对应属性,不会刷新
- 直接修改了没有通知逻辑的自动属性
- 最终的正确实现满足了数据双向绑定的要求:给需要变更通知的属性加了私有backing字段,在setter里主动触发携带正确属性名的
PropertyChanged事件,UI收到通知后就会自动更新绑定的文本内容
如果后续需要CarouselView支持滑动切换题目,直接把ItemsSource换成ObservableCollection<QuestionsClass>类型的全量题目列表即可,列表的增删变更也能自动同步到UI。
内容的提问来源于stack exchange,提问作者user979331
相关产品推荐
相关产品推荐

