首页 > 解决方案 > 绑定到 Entry.Text 的属性设置器无限循环

问题描述

这真让我抓狂。我一直在寻找问题的根源几个小时,但我开始怀疑这不是我的逻辑问题......也许我错了。


问题描述

我有一个简单的Entry。它的Text属性绑定到ViewModel中的double类型的属性。同时,我订阅了EventHandler简单地将属性设置为的事件(实际上我可以重现 x.y0 的问题,即最后一位为 0 的任何小数)。如果现在我在条目中写入任何内容(“1”或“1.”或“1.0”!!!)并离开条目(通过点击外部或点击完成)以便触发,应用程序变得无响应。Unfocused entry.Text"1.0"Unfocused

注意:entry.Text = 1.0我知道在事件处理程序中设置听起来有点奇怪。entry.Text事实是,我通过尝试将值格式化如下遇到了这个问题。

if (double.TryParse(entry.Text, out double result))
{
    entry.Text = String.Format("{0:F2}", result);
}

那里String.Format试图将小数点四舍五入到小数点后两位。如果我给出6.999预期值应该是7.00,但应用程序变得无响应。


重现问题的步骤

  1. 创建空白Xamarin.Forms 项目
  2. 删除MainPage.xaml文件中的默认标签以包含以下Entry,而不是:
<StackLayout>
    <Entry Text="{Binding Weight}"
    Unfocused="entry_Unfocused"/>
</StackLayout>
  1. 在后面的代码中添加以下EventHandler并设置BindingContext页面的属性如下:
public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
    }

    protected override void OnAppearing()
    {
        base.OnAppearing();
        BindingContext = new viewmodel();
    }

    private void entry_Unfocused(object sender, FocusEventArgs e)
    {
        ((Entry)sender).Text = "1.0";
    }

}
  1. 创建ViewModel如下:
public class viewmodel : INotifyPropertyChanged
{
    public viewmodel()
    {
    }

    private double _Weight;
    public double Weight
    {
        get => _Weight;
        set
        {
            if (_Weight != value)
            {
                _Weight = value;
                OnPropertyChanged();
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged([CallerMemberName] String propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
  1. 运行应用程序并在Entry中输入任何内容。
  2. 离开条目以便Unfocused被解雇。

我的系统配置:


谁能解释这里发生了什么,无论如何要解决这个问题?

标签: c#xamarin.formsxamarin.androiddoublestring.format

解决方案


我测试你的代码,调试它,我发现它会无限循环

set
    {
        if (_Weight != value)
        {
            _Weight = value;
            OnPropertyChanged();
        }
    }
}

我认为这是因为您的Weight属性是double类型,它无法string正确设置它,您可以尝试将权重定义为字符串。

private string _Weight;
public string Weight
    {
        get => _Weight;
        set
        {
            if (_Weight != value)
            {
                _Weight = value;
                OnPropertyChanged();
            }
        }
    }

推荐阅读