我的WPF应用程序在使用INotifyPropertyChanged接口时未更新xaml文本块文本

时间:2017-09-13 16:24:57

标签: c# json wpf xaml inotifypropertychanged

我有一个具有一些属性(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);
            }

        }

    }
}

MainWindow Image

1 个答案:

答案 0 :(得分:3)

您有AlertMsg的两个不同实例。

在'MainWindow.xaml'中,您将实例化一个实例作为窗口的数据上下文:

<Window.DataContext>
    <Models:AlertMsg />
</Window.DataContext>

在'PubNubAlerts.cs'中,您将在第19行实例化一个实例:

AlertMsg alertMsg = new AlertMsg();

您需要将窗口DataContext传递给PubNubAlerts,或者需要公开PubNubAlerts使用的实例并将窗口DataContext绑定到该实例。

相关问题