You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET MAUI自定义Entry控件无法从ViewModel获取输入值问题

.NET MAUI自定义ChicEntry双向绑定失效问题排查与修复

问题核心原因

  1. ControlTemplate内部绑定上下文错误:自定义控件XAML中的Entry使用普通Binding,未关联到控件自身的Text/Placeholder属性,导致输入内容无法同步到自定义控件的BindableProperty,进而无法传递给ViewModel。
  2. BindableProperty回调逻辑错误:TextProperty的propertyChanged回调中手动给Text属性赋值,会触发无限循环并干扰BindableProperty的正常值同步机制。
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 07:53:34