简体   繁体   中英

Trigger other Property from binding

I have two entries in a page in my Xamarin Forms app. The Text properties of these two entries are binded with a realm object. Thats a two way binding, so whenever I type in a value in either of these fields, my realm object updates and vice versa. This works just fine.

But my requirement is, when the user changes value in one entry, the value in the other entry also need to be re-calculated and updated. It's like having two entries for a unit conversion (eg mm-inch) - when you change the mm value, it updates the inch value in the other field, and vice versa. How can I achieve this behaviour?

<Label Text="Speed" />
<Entry x:Name="SpeedEntry" Text="{Binding Speed, Mode=TwoWay}" />
<Label  Text="Depth" />
<Entry x:Name="DepthEntry" Text="{Binding Depth, Mode=TwoWay}" />

It sounds like you're following the MVVM pattern (incase you don't you should, because what you're doing is a prime example for how and why to use it)

I suggest putting the calculation in the ViewModel since it increases the opportunity for code reuse (across platforms and possible across projects)

One way of doing it is the following code snippet - there are plenty of others - including Fody.PropertyChanged (reducing the amount of plumbing code needed), Reactive.UI (for reactive programming - also reducing the plumbing) and similar libraries.

using System.ComponentModel;
using System.Runtime.CompilerServices;

public class ConversionViewModel : INotifyPropertyChanged
{

    private double depth;

    private double speed;

    public double Speed {
        get { return this.speed; }
        set {
            this.speed = value;
            this.OnPropertyChanged();
            this.Depth = this.CalculateDepth();
        }
    }

    public double Depth {
        get { return this.depth; }
        set {
            this.depth = value;
            this.OnPropertyChanged();
            this.Speed = this.CalculateSpeed();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private double CalculateSpeed()
    {
        // do your calculation
        return 0;
    }

    private double CalculateDepth()
    {
        // do your calculation
        return 0;
    }

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

}

You could move the calculation to the properties getters to only execute it, when it's actually needed. If it's a relative CPU intensive calculation you'd probably want to cache the result in a field and invalidate it when some properties change.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM