0
votes

I have a bindable property in a custom control (HealthBar):

    public static readonly BindableProperty ValueProperty = BindableProperty.Create(
        nameof(Value),
        typeof(int),
        typeof(HealthBar),
        0,
        BindingMode.TwoWay,
        propertyChanged: ValueChanged);

Is it possible to force the propertychanged (ValueChanged method) to fire even if I'm setting the same value to the property? The ValueChanged method is doing some calculation to set the width of the health bar.

    private static void ValueChanged(BindableObject bindable, object oldValue, object newValue)
    {
        HealthBar obj = bindable as HealthBar;
        if (obj != null)
        {
            obj.RecalculateWidth();
        }
    }

I know this sounds a bit mad, so here are some more details; I need to force the bar to recalculate the width as there are a few of these in a listview, and adding more to the ObservableCollection causes the widths to mess up. Values are being updated via signalR every 2 seconds so the correct width should show next time the Value property is set.

Here is the code that recalcuates the width for clarity:

    private void RecalculateWidth()
    {
        double val = this.Value;
        double max = this.Max;

        double percent = (val / max) * 100;
        double width = (double)this.Width * (double)percent / 100;
        this.bar.Layout(new Rectangle(0, 0, width, this.Height));
    }
1

1 Answers

0
votes

Based on the code posted for RecalculateWidth() - if the values for Value and Max are not changed, forcing the property-changed handling will not help unless the this.Width (of parent control HealthBar) has changed.

So basically, what you want to do is re-calculate the child control's width every time the parent control's width changes.

The easiest way to do this would be to subscribe to it's changes:

protected override void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
    base.OnPropertyChanged(propertyName);

    if (propertyName == nameof(Width))
        this.RecalculateWidth();
}