我有一个具有一些属性(AlertMsg.cs)的类,它使用的是INotifyPropertyChanged接口。使用xaml我将该类的命名空间包含到我的窗口(MainWindow.xaml)。 Intellisense帮我添加了一个datacontext,并使用xaml将这些属性绑定到我的window元素。所以我知道我的窗户知道这些属性。当我在visual studio中运行应用程序时,textblock从类中加载我的构造函数值。所以我感觉很好,因为它被绑在了财产上。
我有另一个类(PubNubAlerts.cs)侦听传入的json,它解析json并将这些值设置为我的属性类(AlertMsg.cs)。这部分也可以正常工作,因为我可以在输出窗口中看到属性发生变化。当属性改变时,它甚至会逐步执行PropertyChanged方法,但是当我查看窗口的UI(MainWindow)时,初始化时加载的构造函数值仍然存在。我希望他们使用传入的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);
}
}
}
}
答案 0 :(得分:3)
您有AlertMsg
的两个不同实例。
在'MainWindow.xaml'中,您将实例化一个实例作为窗口的数据上下文:
<Window.DataContext>
<Models:AlertMsg />
</Window.DataContext>
在'PubNubAlerts.cs'中,您将在第19行实例化一个实例:
AlertMsg alertMsg = new AlertMsg();
您需要将窗口DataContext
传递给PubNubAlerts
,或者需要公开PubNubAlerts
使用的实例并将窗口DataContext
绑定到该实例。