我的WPF应用程序在使用INotifyPropertyChanged接口时没有更新xaml textblock文本
我是WPF的初学者,所以请裸机。我有一个有几个属性的类(AlertMsg.cs),它使用INotifyPropertyChanged接口。使用xaml我将该类的命名空间包含在我的窗口(MainWindow.xaml)中。 Intellisense帮助我添加一个数据上下文,并使用xaml将这些属性绑定到我的窗口元素。所以我知道我的窗户知道属性。当我在Visual Studio中运行应用程序时,textblock会从类中加载我的构造函数值。所以我觉得它被绑定到财产上很不错。我的WPF应用程序在使用INotifyPropertyChanged接口时没有更新xaml textblock文本
我有另一个类(PubNubAlerts.cs),它监听传入的json,它解析json并将这些值设置为我的属性类(AlertMsg.cs)。这部分也工作得很好,因为我可以看到在我的输出窗口中更改的属性。当属性改变它甚至通过PropertyChanged方法时,但当我去看我的窗口(MainWindow)的UI时,在初始化时加载的构造函数值仍然存在。我希望他们使用传入的json数据进行更新。我在执行INotifyPropertyChanged时错过了什么?
MainWindow.xaml
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Models="clr-namespace:MyApplication.Models"
x:Name="AlertPopup" x:Class="MyApplication.MainWindow"
Title="AlertMsg" Height="350" Width="525" WindowState="Normal">
<Window.DataContext>
<Models:AlertMsg />
</Window.DataContext>
<Grid Background="White" Opacity="0.8">
<TabItem Width="500" Height="300" VerticalAlignment="Center" HorizontalAlignment="Center" HorizontalContentAlignment="Center" VerticalContentAlignment="Center">
<Frame Source="MainPage.xaml" MinWidth="100" MinHeight="100" HorizontalAlignment="Center" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" VerticalAlignment="Center" Width="500" Height="297" FontSize="20" />
</TabItem>
<Border Background="{Binding Path=PopUpBackGroundColor, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" BorderBrush="Red" BorderThickness="2" CornerRadius="4" Opacity="0.8" Width="300" Height="80">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="22" Text="{Binding Path=MainMessage, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Foreground="Black"></TextBlock>
</Border>
</Grid>
</Window>
MainWindow.xaml.cs
using System.Windows;
namespace MyApplication
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
WindowState = WindowState.Normal;
WindowStyle = WindowStyle.ThreeDBorderWindow;
Height = 400;
Width = 400;
}
}
}
AlertMsg.cs
using System.ComponentModel;
using System;
namespace MyApplication.Models
{
// interface
class AlertMsg : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged = delegate { };
//// constructor, some default values
public AlertMsg()
{
this.MainMessage = "TEXT GOES HERE";
this.PopUpBackGroundColor = "Red";
}
// main message property
private string mainMessage;
public string MainMessage
{
get
{
return this.mainMessage;
}
set
{
if (value != this.mainMessage)
{
this.mainMessage = value;
System.Diagnostics.Debug.WriteLine("MainMessage is now = " + value);
OnPropertyChanged("MainMessage");
}
}
}
//background color property of message
private string popupBackGroundColor;
public string PopUpBackGroundColor
{
get
{
return this.popupBackGroundColor;
}
set
{
if (value != this.popupBackGroundColor)
{
this.popupBackGroundColor = value;
System.Diagnostics.Debug.WriteLine("popupbackgroundcolor is now = " + value);
OnPropertyChanged("PopUpBackGroundColor");
}
}
}
// call this method on the setter of every property
// should change the text of the view
private void OnPropertyChanged(string propertyName)
{
try
{
// change property
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
System.Diagnostics.Debug.WriteLine("Property " + propertyName + " changed.");
}
}
catch (InvalidAsynchronousStateException e)
{
System.Diagnostics.Debug.WriteLine("Invalid Asynchrounous State Exception" + e.Message);
}
catch (Exception generalException)
{
System.Diagnostics.Debug.WriteLine("Error OnPropertyChanged: " + propertyName + " " + generalException.Message);
}
}
}
}
PubNubAlerts.cs(第三方喂我的JSON。你可以不用担心这一点,因为我知道它更新了我的房产,但为了以防万一,我将它包括在内)。
using System;
using Newtonsoft.Json.Linq;
using PubnubApi;
using MyApplication.Models;
namespace MyApplication
{
public class PubNubAlerts
{
static public Pubnub pubnub;
// hardcoded values for testing
static public string channel = "TestChannel";
static public string authKey = "xxxxxxxxxx";
static public string subscribeKey = "xxxxx-xxxxxx-xxxxx-xxxxxxxx";
static public string channelGroup = "";
static public string mainBody;
AlertMsg alertMsg = new AlertMsg();
public void PubNubSubscribe()
{
// config
PNConfiguration config = new PNConfiguration()
{
AuthKey = authKey,
Secure = false,
SubscribeKey = subscribeKey,
LogVerbosity = PNLogVerbosity.BODY
};
try
{
pubnub = new Pubnub(config);
// add listener
pubnub.AddListener(new SubscribeCallbackExt(
(pubnubObj, message) => {
// grab data from json and parse
System.Diagnostics.Debug.WriteLine(pubnub.JsonPluggableLibrary.SerializeToJsonString(message));
string jsonMessage = pubnub.JsonPluggableLibrary.SerializeToJsonString(message);
dynamic data = JObject.Parse(jsonMessage);
// update alertmsg properties with json from pubnub
alertMsg.MainMessage = data.Message.mainmessage;
alertMsg.PopUpBackGroundColor = data.Message.popupbackgroundcolor;
},
(pubnubObj, presence) => {
System.Diagnostics.Debug.WriteLine(pubnub.JsonPluggableLibrary.SerializeToJsonString(presence));
},
(pubnubObj, status) => {
System.Diagnostics.Debug.WriteLine("{0} {1} {2} ", status.Operation, status.Category, status.StatusCode);
}
));
System.Diagnostics.Debug.WriteLine("Running subscribe()");
// subscribe
pubnub.Subscribe<object>()
.WithPresence()
.Channels(channel.Split(','))
.ChannelGroups(channelGroup.Split(','))
.Execute();
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine("FAILED TO SUBSCRIBE: " + e.Message);
}
}
}
}
你有AlertMsg
两个不同的实例。
在“MainWindow.xaml”你实例化一个实例为您在这里窗口的数据上下文:
<Window.DataContext>
<Models:AlertMsg />
</Window.DataContext>
而在“PubNubAlerts.cs”你是在第19行实例化一个实例:
AlertMsg alertMsg = new AlertMsg();
您需要将窗口的DataContext
传递给PubNubAlerts
,或者需要公开PubNubAlerts
使用的实例并将窗口的DataContext
绑定到该实例。
所以是的,有两个不同的任何事情是行不通的。我在pubnub内创建了一个属性,并将其公开并将datacontext切换到pubnub属性,并开始更新我的MainWindow。非常感谢你。 – jackT