C# 绑定到静态属性未响应PropertyChanged

C# 绑定到静态属性未响应PropertyChanged,c#,wpf,xaml,data-binding,C#,Wpf,Xaml,Data Binding,我对XAML和WPF相当陌生,已经阅读了许多关于如何绑定控件属性的示例,但似乎没有一个适用于我的问题 我有一个继承INotifyPropertyChanged的静态类分析 代码摘要如下 class Analyse : INotifyPropertyChanged { public static DataSet moodleData; // Dataset containing the log data for analysis private static bool dataP

我对XAML和WPF相当陌生,已经阅读了许多关于如何绑定控件属性的示例,但似乎没有一个适用于我的问题

我有一个继承INotifyPropertyChanged的静态类分析

代码摘要如下

class Analyse : INotifyPropertyChanged
{
    public static DataSet moodleData;  // Dataset containing the log data for analysis
    private static bool dataPresent = true;

    public static Boolean DataPresent
    {
        get { return dataPresent; }
        set
        {
            if (dataPresent != value)
            {
                dataPresent = value;
                NotifyStaticPropertyChanged("DataPresent");
            }
        }
    }

    public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged
     = delegate { };

    private static void NotifyStaticPropertyChanged(string propertyName)
    {
        StaticPropertyChanged(null, new PropertyChangedEventArgs(propertyName));
    }


    #endregion

    public static void clearData()
    {
        try
        {
            moodleData.Clear();
            DataPresent = false;
        }
        catch { }
    }
}
类分析:INotifyPropertyChanged
{
公共静态数据集moodleData;//包含用于分析的日志数据的数据集
私有静态bool dataPresent=true;
公共静态布尔数据存在
{
获取{return dataPresent;}
设置
{
如果(数据存在!=值)
{
数据当前=价值;
NotifyStaticPropertyChanged(“DataPresent”);
}
}
}
公共静态事件EventHandler StaticPropertyChanged
=委托{};
私有静态void NotifyStaticPropertyChanged(字符串propertyName)
{
StaticPropertyChanged(空,新PropertyChangedEventArgs(propertyName));
}
#端区
公共静态void clearData()
{
尝试
{
moodleData.Clear();
DataPresent=false;
}
捕获{}
}
}
我的XAML包含本地名称空间

<Window x:Name="TheMainWindow" x:Class="MoodleLogAnalyse.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    DataContext="{Binding Mode=OneWay, RelativeSource={RelativeSource Self}}"

    xmlns:local="clr-namespace:MoodleLogAnalyse"

    Title="MainWindow" Height="556.88" Width="793" WindowStartupLocation="CenterScreen">

而且按钮绑定正确

<Button Name="OpenButton" Command="Open" 
       IsEnabled="{Binding Source={x:Static local:Analyse.DataPresent},
       Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"  
       Content="Open Grades" />

属性肯定绑定到IsEnabled,在代码中手动更改dataPresent定义可启用和禁用按钮,但动态更改(如在true和false之间切换,如调用clear data方法)不会在运行时更改按钮的IsEnabled状态

属性更改事件正在触发,因为我已插入要检查的断点


我看不出我在这方面出了什么问题!任何帮助都将不胜感激。

使用
Source
属性存储将用作替代绑定源的对象(默认情况下,绑定使用
DataContext

但是当您指定
Path
属性时,绑定将定位静态类并绑定到该属性。在这种情况下,static
DataPresent
属性是源,而
StaticPropertyChanged
事件用于通知绑定更新

无法在绑定到静态属性的情况下使用
INotifyPropertyChanged
,因为没有用于访问该属性的实例。必须改用相应的静态事件

事件的名称必须等于
StaticPropertyChanged
,其类型必须为
EventHandler
。或者名称必须由两部分组成:属性名称和后缀
已更改
。在最后一种情况下,事件的类型必须是
EventHandler
,因为事件只通知相应属性的更改

这意味着:

  • Analyze
    可以是静态的,因为不需要
    INotifyPropertyChanged
  • 事件
    StaticPropertyChanged
    可以重命名为
    DataPresentChanged
    ,其类型可以更改为
    EventHandler
  • 换言之:

    public static class Analyze
    {
        public static DataSet moodleData;  // Dataset containing the log data for analysis
        private static bool dataPresent = true;
    
        public static Boolean DataPresent
        {
            get { return dataPresent; }
            set
            {
                if (dataPresent != value)
                {
                    dataPresent = value;
                    DataPresentChanged(null, EventArgs.Empty);
                }
            }
        }
    
        public static event EventHandler DataPresentChanged = delegate { };
    }
    
    有用链接:


  • 有趣的评论,但无助于解决问题!实际上,由于WPF4.5,它应该与StaticPropertyChanged事件一起工作。但是,您的绑定应该是
    {binding Path=(local:analysis.DataPresent),…}
    。您可以改为将类声明为静态:
    staticclassanalysis{…}
    @Clemens感谢您的帮助。你能解释一下两者之间的区别吗,{Binding Path=(local:analysis.DataPresent)和{Binding Source={x:Static local:analysis.DataPresent}对于其他愿意阅读这篇文章的人来说。@Clemens你是对的,它不需要继承,似乎有点奇怪,但这可能正是我需要多读一点来理解的原因。@Stephen Smith-你应该将此标记为你问题的答案。感谢你们两人的评论和回复,他们都非常有帮助和见解,呵呵佩弗利,他们会帮助别人,而不仅仅是我!伙计们,这就是你们要寻找的语法。
    <Button IsEnabled="{Binding Path=(local:Analyze.DataPresent)}" />
    
    public static class Analyze
    {
        public static DataSet moodleData;  // Dataset containing the log data for analysis
        private static bool dataPresent = true;
    
        public static Boolean DataPresent
        {
            get { return dataPresent; }
            set
            {
                if (dataPresent != value)
                {
                    dataPresent = value;
                    DataPresentChanged(null, EventArgs.Empty);
                }
            }
        }
    
        public static event EventHandler DataPresentChanged = delegate { };
    }