StackLayout绑定ViewModel不生效且触发空引用异常如何解决
问题根因
- 绑定属性使用错误:
BindableLayout.ItemTemplate是用来为集合类布局指定子项模板的属性,要求传入DataTemplate类型的值,你直接绑定StackLayout实例会导致类型不匹配,框架解析时就会抛出空引用异常。 - 设计逻辑不符合MVVM规范:ViewModel层不应该持有任何View层的控件实例,你在ViewModel中初始化的
CreateQuizPageQuizNameSL根本不是页面上实际渲染的那个StackLayout,就算不抛异常,操作这个实例也不会对页面生效。
正确实现方案
要实现点击按钮隐藏布局的需求,只需要在ViewModel中定义控制显隐的布尔属性,将StackLayout的IsVisible属性绑定到该属性即可,无需在ViewModel中引用控件。
修改后的XAML代码
<FlexLayout> <!-- 移除错误的BindableLayout.ItemTemplate绑定,添加IsVisible属性绑定 --> <StackLayout IsVisible="{Binding IsQuizNameLayoutVisible}"> <Label Text="Create New Quiz" /> <StackLayout > <Entry Text="{Binding QuizNameInput}" Placeholder="Enter quiz name"/> </StackLayout> </StackLayout> <Button Command="{Binding SubmitCreateQuizCommand}" Text="Create my quiz now!"></Button> </FlexLayout>
修改后的ViewModel代码
需要实现INotifyPropertyChanged接口来触发界面更新:
using System.ComponentModel; using System.Runtime.CompilerServices; // 若使用Xamarin.Forms则替换为using Xamarin.Forms; using Microsoft.Maui.Controls; internal class CreateQuizPageViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } private string _quizNameInput; public string QuizNameInput { get => _quizNameInput; set { _quizNameInput = value; OnPropertyChanged(); } } private bool _isQuizNameLayoutVisible = true; public bool IsQuizNameLayoutVisible { get => _isQuizNameLayoutVisible; set { _isQuizNameLayoutVisible = value; OnPropertyChanged(); } } public Command SubmitCreateQuizCommand { get; set; } public CreateQuizPageViewModel() { SubmitCreateQuizCommand = new Command(OnSubmitCreateNewQuizClick); } public void OnSubmitCreateNewQuizClick() { // 直接修改属性即可控制布局显隐 IsQuizNameLayoutVisible = false; } }
内容的提问来源于stack exchange,提问作者Anjimlio
相关产品推荐
相关产品推荐

