绑定到Entry.Text的属性的设置器无限循环 [英] Setter of property bound to Entry.Text loops infinitely

查看:135
本文介绍了绑定到Entry.Text的属性的设置器无限循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这让我发疯.我一直在寻找问题的根源已有好几个小时,但我开始怀疑这不是我的逻辑问题……也许我错了.

This is driving me crazy. I have been looking for the source of the issue for hours, but i am starting to suspect this is not an issue in my logic... Maybe i am wrong.

我有一个简单的条目.其 Text 属性绑定到 ViewModel 中类型为 double 的属性.同时,我订阅了Unfocused Event ,其 EventHandler 只是将entry.Text属性设置为"1.0"(实际上,我可以重现x.y0的问题. ,即最终数字为0的任何十进制).如果现在我在 Entry 中输入任何内容("1","1"或"1.0"除外!!!!!!)并留下 Entry (通过在外部点击或点击). (完成)上),从而触发Unfocused应用将无响应.

I have a simple Entry. Its Text property is bound to a property with type double in a ViewModel. At the same time i subscribe to the Unfocused Event whose EventHandler simply sets the entry.Text property to "1.0" (actually i can reproduce the issue for x.y0, that is any decimal whose final digit is 0). If now i write in the Entry anything (except "1" or "1." or "1.0"!!!) and leave the Entry (by tapping outside or taping on Done) so that Unfocused is fired, the App becomes unresponsive.

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

Note: I know that it sounds a bit strange to set entry.Text = 1.0 in the event handler. The truth is that i came across this issue by trying to format the entry.Text value as follows.

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

String.Format试图将小数点四舍五入到两个小数点.如果我给出6.999,则预期值应为7.00,但 App 却变得无响应.

There String.Format tries to round the decimal to two decimals. If i give 6.999 the expected value should be 7.00, but the App becomes unresponsive instead.

  1. 创建空白的 Xamarin.Forms 产品.
  2. 删除 MainPage.xaml 文件中的默认标签,以包括以下条目:
  1. Create blank Xamarin.Forms proyect.
  2. Remove default Label in MainPage.xaml file to include following Entry, instead:

<StackLayout>
    <Entry Text="{Binding Weight}"
    Unfocused="entry_Unfocused"/>
</StackLayout>

  1. 在后面的代码中添加以下 EventHandler 并按如下所示设置页面的BindingContext属性:
  1. In the code behind add the following EventHandler and set the BindingContext property of the page as follows:

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 ,例如:
  1. Create the ViewModel like:

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. 运行该应用,然后在条目中键入任何内容.
  2. 离开条目,以便触发Unfocused.
  1. Run the App and type anything into the Entry.
  2. Leave the Entry so that Unfocused is fired.


我的系统配置:

  • Visual Studio v.16.3.8
  • Xamarin.Forms 4.2.0.709249
  • Android 8

  • My System configuration:

    • Visual Studio v. 16.3.8
    • Xamarin.Forms 4.2.0.709249
    • Android 8
    • 任何人都可以解释这里发生的事情,以及解决该问题的方法吗?

      Could anyone explain what is going on here, and anyway to work around this issue?

      推荐答案

      我找到了问题的根源!

      I found the source of the Issue!

      感谢@ LeoZhu-MSFT的见识!

      Thanks to @LeoZhu-MSFT for his insight!

      问题是,当设置了entry.Text = "3.00"时,该值显然会被解析为double值,然后发送给我的属性设置器.实际上:

      The thing is that when entry.Text = "3.00" is set, this value is apparently parsed to double and then send to my property setter. In fact:

      double _Weight = double.Parse("3.00"); // _Weight ends up having value 3!!! 
      

      因此entry.Text_Weight始终具有不同的值!!!并且绑定尝试将_Weight无限期设置为3.00,但_Weight进入设置器的全部是3 ...

      So entry.Text and _Weight have always different values!!! and the binding tries to set indefinitely _Weight to 3.00 but all _Weight gets in the setter is 3...

      要解决此问题,而不是像@ LeoZhu-MSFT所建议的那样,将属性_Weight更改为 String ,这是次优的选择(我仍然想对我的Weight执行数学运算属性!),我可以将其更改为十进制 !!!!

      To solve that, instead of changing my property _Weight to String as suggested by @LeoZhu-MSFT, which is sub-optimal (i still want to perform mathematical operations with my Weight property!), i can change it to decimal!!!

      事实上:

      decimal _Weight = decimal.Parse("3.00"); // _Weight has now value 3.00. As wanted!!!
      

      因此,在我的 View Model 中将_WeightWeight类型更改为 decimal 后,无限循环行为消失了:D

      So after i change _Weight and Weight type to decimal in my View Model, the infinite-loop-behavior disappeared :D

      这篇关于绑定到Entry.Text的属性的设置器无限循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆