.NET MAUI自定义Entry控件无法从ViewModel获取输入值问题
.NET MAUI自定义ChicEntry双向绑定失效问题排查与修复
问题核心原因
- ControlTemplate内部绑定上下文错误:自定义控件XAML中的Entry使用普通
Binding,未关联到控件自身的Text/Placeholder属性,导致输入内容无法同步到自定义控件的BindableProperty,进而无法传递给ViewModel。 - BindableProperty回调逻辑错误:TextProperty的
propertyChanged回调中手动给Text属性赋值,会触发无限循环并干扰BindableProperty的正常值同步机制。 - ViewModel属性拼写错误(示例笔误):代码中
FulltName存在拼写错误,应为FullName,但这是局部问题,核心失效原因仍为控件绑定逻辑错误。
修复步骤
1. 修正ControlTemplate内部绑定方式
将Entry的绑定改为TemplateBinding,明确关联到自定义控件的属性:
<?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" x:Class="BlogTemplate.ControlTemplates.ChicEntry"> <ContentView.Resources> <ControlTemplate x:Key="ChicEntryControlTemplate"> <Border StrokeThickness="0" StrokeShape="RoundRectangle 10"> <!-- 使用TemplateBinding绑定到自定义控件自身属性 --> <Entry Text="{TemplateBinding Text, Mode=TwoWay}" Placeholder="{TemplateBinding Placeholder}" Margin="8,0,8,0" BackgroundColor="{AppThemeBinding Light={StaticResource CardColorLight}, Dark={StaticResource CardColorDark}}"/> </Border> </ControlTemplate> </ContentView.Resources> </ContentView>
注:Placeholder无需设置TwoWay模式,仅需单向传递即可。
2. 移除错误的BindableProperty回调
删除TextProperty中多余的propertyChanged回调,依赖BindableProperty的默认值同步逻辑:
using static System.Net.Mime.MediaTypeNames; namespace BlogTemplate.ControlTemplates; public partial class ChicEntry : ContentView { public static readonly BindableProperty TextProperty = BindableProperty.Create(nameof(Text), typeof(string), typeof(ChicEntry), string.Empty); public static readonly BindableProperty PlaceholderProperty = BindableProperty.Create(nameof(Placeholder), typeof(string), typeof(ChicEntry), string.Empty); public string Text { get => (string)GetValue(TextProperty); set => SetValue(TextProperty, value); } public string Placeholder { get => (string)GetValue(PlaceholderProperty); set => SetValue(PlaceholderProperty, value); } public ChicEntry() { InitializeComponent(); // 可选优化:直接在控件内部设置ControlTemplate,避免页面重复指定 this.ControlTemplate = Resources["ChicEntryControlTemplate"] as ControlTemplate; } }
3. 修正ViewModel属性拼写与绑定基础
- 修正拼写错误:将
FulltName改为FullName - 确保ViewModel实现
INotifyPropertyChanged接口(双向绑定必备):
public class SignUpViewModel : INotifyPropertyChanged { private string _fullName; public string FullName { get => _fullName; set { _fullName = value; OnPropertyChanged(); } } // 其他属性(如Email)需同理实现属性变更通知 public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } // 构造函数与命令代码... public SignUpViewModel() { Title = AppResources.SignUp; SignUpCommand = new Command(SignUp); LoginCommand = new Command(async () => await Shell.Current.GoToAsync("..")); } private void SignUp(object obj) { var user = FullName; // 已修正拼写 } }
4. 页面控件的正确使用
确保页面BindingContext为ViewModel实例,并绑定正确的属性名:
<template:ChicEntry Text="{Binding FullName, Mode=TwoWay}"/>
注:如果已在自定义控件构造函数中设置ControlTemplate,无需重复指定该属性。
内容的提问来源于stack exchange,提问作者user2474503
相关产品推荐
相关产品推荐

