简体   繁体   中英

Why binding is not enough to refresh UI in WP7 (MVVM)

I'm trying to create WP7 application based on MVVM pattern but I have problem with refreshing bind content of TextBlock. In the current state I need to reopen page to refresh content. I think that it's related to setting data context but I couldn't fix it.

PropertyChangedEventHandler in ViewModel.cs

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

    private string _txtStatus = "";
    public string TxtStatus
    {
        get { return _txtStatus; }
        set
        {
            _txtStatus = value;
            NotifyPropertyChanged("TxtStatus");
        }
    }

ViewModel Property in App.xaml.cs

public partial class App : Application
{
    private static ViewModel _viewModel { get; set; }
    public static ViewModel ViewModel
    {
        get { return _viewModel ?? (_viewModel = new ViewModel()); }
    }

Setting DataContext in StatusPage.xaml.cs

public partial class Status : PhoneApplicationPage
{
    public Status()
    {
        InitializeComponent();
        DataContext = App.ViewModel;
    }

Binding in StatusPage.xaml

<TextBlock x:Name="TxtStatus" Text="{Binding Path=TxtStatus, Mode=OneWay}" Width="450" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Top" />

UPDATE 1

Setting value of TxtStatus in MqttService.cs

public class MqttService
{
    private readonly ViewModel _viewModel;

    public MqttService(ViewModel viewModel)
    {
        _viewModel = viewModel;
    }

    private void Log(string log)
    {
        _viewModel.TxtStatus = _viewModel.TxtStatus + log;
    }

    private void Connect()
    {
        _client.Connect(true);
        Log(MsgConnected + _viewModel.TxtBrokerUrl + ", " + _viewModel.TxtClientId + "\n");
        _viewModel.IsConnected = true;
    }

MqttService Property in ViewModel.cs

    private MqttService _mqttService;
    public MqttService MqttService
    {
        get { return _mqttService ?? (_mqttService = new MqttService(this)); }
    }

Now I wonder if maybe I have some kind of the circular reference problem (MqttService-ViewModel). I'm not sure, it looks good to me.

Your code works fine for me in WPF .NET4.0

so maybe your Property TxtStatus never get a string

_txtStatus ="new status"; // wrong
TxtStatus = "new status"; // right

or you get some interfering with your x:Name="TxtStatus" but that would be an Windows-Phone-7 based problem

Thank You all. After Erno de Weerd and ken2k wrote comments about threads I did some research and found this: Notify the UI Thread from Background Thread . I changed the way of setting value of the TxtStatus and it's working perfectly now. :)

(bad) Setting value of TxtStatus in MqttService.cs

private void Log(string log)
{
    _viewModel.TxtStatus = _viewModel.TxtStatus + log;
}

(good) Setting value of TxtStatus in MqttService.cs

private void Log(string log)
{
    Deployment.Current.Dispatcher.BeginInvoke(() =>
    {
        App.ViewModel.TxtStatus = log + App.ViewModel.TxtStatus;
    });
}

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