FetFrumos
FetFrumos

Reputation: 5944

MVVMCross Android: value with binding not updated

I created simple app with Xamarin(Android)+Mvvmcross. I have property Data( type MyData) in my ViewModel.

This is my VievModel

public class MyViewModel:MvxViewModel
{
    private MyData _data;
    public MyData Data
    {
        get { return _data; }
        set
        {
            _data = value;
            RaisePropertyChanged(() => Data);
        }
    }
    ....
}

public class MyData: INotifyPropertyChanged
{
    public string Current
    {
        get { return _current; }
        set
        {
            _current = value;
            Debug.WriteLine(_current);
            NotifyPropertyChanged("Current");
        }
    }
    private string _current;

    public event PropertyChangedEventHandler PropertyChanged;
    public void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

I use this binding in view

 xmlns:local="http://schemas.android.com/apk/res-auto"

<TextView
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 local:MvxBind="Text Data.Current"
 android:id="@+id/textView" />

This is my Timer:

 private Timer _timer;
 .....
 public void InitEvent(Action action)
 {
     _timer.Elapsed += TimerTick;
     _action = action;
 }

 private void TimerTick(object sender, ElapsedEventArgs e)
 {
     if (_action != null)
            _action(); 
 }

In _action updated proprrty Current.

When value property is updated Text in TextView does not changed. What is the problem? The value is changed on the timer. Debug.WriteLine(_current) - shows new value. TextView.Text - old value, not updated.

Upvotes: 1

Views: 1829

Answers (1)

Stuart
Stuart

Reputation: 66882

Is your "timer" running on a background thread?

If it is, then you'll need to find some way to signal the RaisePropertyChanged on the UI thread.

One easy way to do this is to inherit from MvxNotifyPropertyChanged - it will automatically marshal the notification on to the UI.

Another is to use IMvxMainThreadDispatcher - e.g.

public string Current
{
    get { return _current; }
    set
    {
        _current = value;
        Debug.WriteLine(_current);
        Mvx.Resolve<IMvxMainThreadDispatcher>()
           .RequestMainThreadAction(() => NotifyPropertyChanged("Current"));
    }
}

Of course, if multiple threads are accessing set Current then you may also hit weird threading bugs...

Upvotes: 5

Related Questions