我的 WPF 应用程序在使用 INotifyPropertyChanged 接口时没有更新 xaml 文本块文本
My WPF application is not updating the xaml textblock text while using INotifyPropertyChanged interface
我有一个 class,它有几个属性 (AlertMsg.cs),它使用 INotifyPropertyChanged 接口。使用 xaml 我将那个 class 的命名空间包含到我的 window (MainWindow.xaml) 中。 Intellisense 帮助我添加了一个数据上下文,并仅使用 xaml 将这些属性绑定到我的 window 元素。所以我知道我的 window 知道这些属性。当我 运行 visual studio 中的应用程序时,文本块从 class 加载我的构造函数值。所以我对它绑定到 属性 感觉很好。
我有另一个 class (PubNubAlerts.cs) 侦听传入的 json,它解析 json 并将这些值设置为我的 属性 class (AlertMsg.cs)。这部分也工作得很好,因为我可以看到输出中的属性发生了变化 window。当属性更改时,它甚至会逐步执行 PropertyChanged 方法,但是当我查看 UI 的 window(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);
}
}
}
}
MainWindow Image
您有两个不同的 AlertMsg
实例。
在 'MainWindow.xaml' 中,您在此处将实例实例化为 window 的数据上下文:
<Window.DataContext>
<Models:AlertMsg />
</Window.DataContext>
并且在 'PubNubAlerts.cs' 中,您在第 19 行附近实例化了一个实例:
AlertMsg alertMsg = new AlertMsg();
您需要将您的 window 的 DataContext
传递给 PubNubAlerts
,或者您需要公开 PubNubAlerts
使用的实例并绑定您的 window的 DataContext
到它。
我有一个 class,它有几个属性 (AlertMsg.cs),它使用 INotifyPropertyChanged 接口。使用 xaml 我将那个 class 的命名空间包含到我的 window (MainWindow.xaml) 中。 Intellisense 帮助我添加了一个数据上下文,并仅使用 xaml 将这些属性绑定到我的 window 元素。所以我知道我的 window 知道这些属性。当我 运行 visual studio 中的应用程序时,文本块从 class 加载我的构造函数值。所以我对它绑定到 属性 感觉很好。
我有另一个 class (PubNubAlerts.cs) 侦听传入的 json,它解析 json 并将这些值设置为我的 属性 class (AlertMsg.cs)。这部分也工作得很好,因为我可以看到输出中的属性发生了变化 window。当属性更改时,它甚至会逐步执行 PropertyChanged 方法,但是当我查看 UI 的 window(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);
}
}
}
}
MainWindow Image
您有两个不同的 AlertMsg
实例。
在 'MainWindow.xaml' 中,您在此处将实例实例化为 window 的数据上下文:
<Window.DataContext>
<Models:AlertMsg />
</Window.DataContext>
并且在 'PubNubAlerts.cs' 中,您在第 19 行附近实例化了一个实例:
AlertMsg alertMsg = new AlertMsg();
您需要将您的 window 的 DataContext
传递给 PubNubAlerts
,或者您需要公开 PubNubAlerts
使用的实例并绑定您的 window的 DataContext
到它。