C# 为什么绑定不足以刷新WP7(MVVM)中的UI

C# 为什么绑定不足以刷新WP7(MVVM)中的UI,c#,windows-phone-7,data-binding,mvvm,C#,Windows Phone 7,Data Binding,Mvvm,我正在尝试基于MVVM模式创建WP7应用程序,但在刷新TextBlock的绑定内容时遇到问题在当前状态下,我需要重新打开页面以刷新内容。我认为这与设置数据上下文有关,但我无法修复它 ViewModel.cs中的PropertyChangedEventHandler public class ViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; p

我正在尝试基于MVVM模式创建WP7应用程序,但在刷新TextBlock的绑定内容时遇到问题在当前状态下,我需要重新打开页面以刷新内容。我认为这与设置数据上下文有关,但我无法修复它

ViewModel.cs中的PropertyChangedEventHandler

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");
        }
    }
public partial class App : Application
{
    private static ViewModel _viewModel { get; set; }
    public static ViewModel ViewModel
    {
        get { return _viewModel ?? (_viewModel = new ViewModel()); }
    }
public partial class Status : PhoneApplicationPage
{
    public Status()
    {
        InitializeComponent();
        DataContext = App.ViewModel;
    }
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;
    }
    private MqttService _mqttService;
    public MqttService MqttService
    {
        get { return _mqttService ?? (_mqttService = new MqttService(this)); }
    }
private void Log(string log)
{
    _viewModel.TxtStatus = _viewModel.TxtStatus + log;
}
private void Log(string log)
{
    Deployment.Current.Dispatcher.BeginInvoke(() =>
    {
        App.ViewModel.TxtStatus = log + App.ViewModel.TxtStatus;
    });
}
App.xaml.cs中的ViewModel属性

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");
        }
    }
public partial class App : Application
{
    private static ViewModel _viewModel { get; set; }
    public static ViewModel ViewModel
    {
        get { return _viewModel ?? (_viewModel = new ViewModel()); }
    }
public partial class Status : PhoneApplicationPage
{
    public Status()
    {
        InitializeComponent();
        DataContext = App.ViewModel;
    }
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;
    }
    private MqttService _mqttService;
    public MqttService MqttService
    {
        get { return _mqttService ?? (_mqttService = new MqttService(this)); }
    }
private void Log(string log)
{
    _viewModel.TxtStatus = _viewModel.TxtStatus + log;
}
private void Log(string log)
{
    Deployment.Current.Dispatcher.BeginInvoke(() =>
    {
        App.ViewModel.TxtStatus = log + App.ViewModel.TxtStatus;
    });
}
在StatusPage.xaml.cs中设置DataContext

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");
        }
    }
public partial class App : Application
{
    private static ViewModel _viewModel { get; set; }
    public static ViewModel ViewModel
    {
        get { return _viewModel ?? (_viewModel = new ViewModel()); }
    }
public partial class Status : PhoneApplicationPage
{
    public Status()
    {
        InitializeComponent();
        DataContext = App.ViewModel;
    }
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;
    }
    private MqttService _mqttService;
    public MqttService MqttService
    {
        get { return _mqttService ?? (_mqttService = new MqttService(this)); }
    }
private void Log(string log)
{
    _viewModel.TxtStatus = _viewModel.TxtStatus + log;
}
private void Log(string log)
{
    Deployment.Current.Dispatcher.BeginInvoke(() =>
    {
        App.ViewModel.TxtStatus = log + App.ViewModel.TxtStatus;
    });
}
在StatusPage.xaml中绑定

<TextBlock x:Name="TxtStatus" Text="{Binding Path=TxtStatus, Mode=OneWay}" Width="450" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Top" />
ViewModel.cs中的MqttService属性

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");
        }
    }
public partial class App : Application
{
    private static ViewModel _viewModel { get; set; }
    public static ViewModel ViewModel
    {
        get { return _viewModel ?? (_viewModel = new ViewModel()); }
    }
public partial class Status : PhoneApplicationPage
{
    public Status()
    {
        InitializeComponent();
        DataContext = App.ViewModel;
    }
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;
    }
    private MqttService _mqttService;
    public MqttService MqttService
    {
        get { return _mqttService ?? (_mqttService = new MqttService(this)); }
    }
private void Log(string log)
{
    _viewModel.TxtStatus = _viewModel.TxtStatus + log;
}
private void Log(string log)
{
    Deployment.Current.Dispatcher.BeginInvoke(() =>
    {
        App.ViewModel.TxtStatus = log + App.ViewModel.TxtStatus;
    });
}

现在我想知道是否有某种循环引用问题(MqttService ViewModel)。我不确定,我觉得不错。

您的代码在
WPF
.NET4.0

因此,您的属性
TxtStatus
可能永远不会得到字符串

_txtStatus ="new status"; // wrong
TxtStatus = "new status"; // right
或者您的
x:Name=“TxtStatus”
会受到一些干扰,但这将是一个基于Windows-Phone-7的问题,谢谢大家。在写了关于线程的评论之后,我做了一些研究,发现了以下内容:。我改变了TxtStatus的设置方式,现在它工作得很好。:)

(错误)MqttService.cs中TxtStatus的设置值

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");
        }
    }
public partial class App : Application
{
    private static ViewModel _viewModel { get; set; }
    public static ViewModel ViewModel
    {
        get { return _viewModel ?? (_viewModel = new ViewModel()); }
    }
public partial class Status : PhoneApplicationPage
{
    public Status()
    {
        InitializeComponent();
        DataContext = App.ViewModel;
    }
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;
    }
    private MqttService _mqttService;
    public MqttService MqttService
    {
        get { return _mqttService ?? (_mqttService = new MqttService(this)); }
    }
private void Log(string log)
{
    _viewModel.TxtStatus = _viewModel.TxtStatus + log;
}
private void Log(string log)
{
    Deployment.Current.Dispatcher.BeginInvoke(() =>
    {
        App.ViewModel.TxtStatus = log + App.ViewModel.TxtStatus;
    });
}
(良好)MqttService.cs中TxtStatus的设置值

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");
        }
    }
public partial class App : Application
{
    private static ViewModel _viewModel { get; set; }
    public static ViewModel ViewModel
    {
        get { return _viewModel ?? (_viewModel = new ViewModel()); }
    }
public partial class Status : PhoneApplicationPage
{
    public Status()
    {
        InitializeComponent();
        DataContext = App.ViewModel;
    }
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;
    }
    private MqttService _mqttService;
    public MqttService MqttService
    {
        get { return _mqttService ?? (_mqttService = new MqttService(this)); }
    }
private void Log(string log)
{
    _viewModel.TxtStatus = _viewModel.TxtStatus + log;
}
private void Log(string log)
{
    Deployment.Current.Dispatcher.BeginInvoke(() =>
    {
        App.ViewModel.TxtStatus = log + App.ViewModel.TxtStatus;
    });
}

输出视图中有任何绑定错误吗?我看不出您的代码有任何错误。您如何更新要在文本块中显示的值?也许您可以添加一个
,UpdateSourceTrigger=PropertyChanged
应用程序中是否存在多线程?更具体地说,
TxtStatus
是否在UI线程中更新?您可以在ViewModel上TxtStatus的setter中设置断点,并查看更新属性时是否命中它。如果它被击中,你可能有2个并发视图模型;一个连接到视图,另一个连接到服务。