WPF:未使用INotifyPropertyChanged更新UI

Spa*_*eak 0 c# wpf datacontext xaml

我目前正在学习WPF,DataContexts和DataBinding.我的目标是使用一个任务栏任务(使用NotifyIconWpf),该任务具有运行后台的连续线程来监视网络.

我设法获得绑定到ProgramClock类的UI元素(显示在屏幕截图中),但是当ProgramClock更改时它不会更新,很可能是因为INotifyPropertyChanged参数中的某些内容是错误的.

我发现最接近的类似问题是UI未更新INotifyPropertyChanged但是我无法弄清楚要在XAML中更改DataPath的内容,或者如何使INotifyPropertyChanged正常工作.

请注意,BackgroundWorker线程成功更新了App的静态ProgramClock(使用单独的WinForm进行检查),并且该时间最初是在WPF中加载的,因此可能没有正确调用PropertyChanged.

在此输入图像描述

ProgramClock

public class ProgramClock : INotifyPropertyChanged
    {
        private DateTime _myTime;
        public event PropertyChangedEventHandler PropertyChanged;
        private ClockController clockController;

        public ProgramClock()
        {

            this._myTime = DateTime.Now;
            clockController = new ClockController();

            MessageBox.Show("created new clock");
        }

        public DateTime MyTime
        {
            get
            {
                return this._myTime;
            }

            set
            {
                if (_myTime == value) return;
                _myTime = value;

                //System.Windows.Forms.MessageBox.Show(PropertyChanged.ToString());
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs(_myTime.ToString()));
            }
        }

        public string MyTimeString
        {
            get { return this._myTime.ToString(); }
        }

        public void UpdateTime()
        {
            this.MyTime = DateTime.Now;
        }
    }
Run Code Online (Sandbox Code Playgroud)

泡泡CS

public partial class InfoBubble : System.Windows.Controls.UserControl
{

    public InfoBubble()
    {
        InitializeComponent();
        this.DataContext = App.ClockBindingContainer;
    }
}
Run Code Online (Sandbox Code Playgroud)

泡泡XAML

<UserControl x:Class="FileWatcher.Controls.InfoBubble"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008">
    <Border
        Background="White"
        BorderBrush="Orange"
        BorderThickness="2"
        CornerRadius="4"
        Opacity="1"
        Width="160"
        Height="40">
            <TextBlock
          Text="{Binding Path=MyTimeString}"
          HorizontalAlignment="Center"
          VerticalAlignment="Center" />
    </Border>
</UserControl>
Run Code Online (Sandbox Code Playgroud)

主要应用

public partial class App : System.Windows.Application
{

    private TaskbarIcon tb;
    private ResourceDictionary _myResourceDictionary;
    public static ProgramClock _programClock = new ProgramClock();

    private void Application_Startup(object sender, StartupEventArgs e)
    {
        NotifIconStarter();
    }

    public static ProgramClock ClockBindingContainer
    {
        get { return _programClock; }
    }
}
Run Code Online (Sandbox Code Playgroud)

Dan*_*ley 5

一个问题是你调用PropertyChanged事件.您需要将正在更改的属性的名称传递给PropertyChangedEventArgs 新值.

所以使用:

if (PropertyChanged != null)
    PropertyChanged(this, new PropertyChangedEventArgs("MyTime"));
Run Code Online (Sandbox Code Playgroud)

代替:

if (PropertyChanged != null)
    PropertyChanged(this, new PropertyChangedEventArgs(_myTime.ToString()));
Run Code Online (Sandbox Code Playgroud)

但是,您实际上是绑定到另一个属性 - MyTimeString.

最终,您要约束的财产需要举办活动.

  • @SpaceSteak为什么不是这个答案?O_O (2认同)