【问题标题】:Binding to a static property is not responding to PropertyChanged绑定到静态属性不响应 PropertyChanged
【发布时间】:2015-05-09 10:07:13
【问题描述】:

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

我有一个静态类Analyze,它继承了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 { }
    }
}

我的 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状态运行时的按钮。

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

我看不出我哪里出了问题!任何帮助将不胜感激。

【问题讨论】:

  • 有趣的评论但无助于解决问题!
  • 实际上,从 WPF 4.5 开始,它应该与 StaticPropertyChanged 事件一起使用。但是,您的绑定应该是{Binding Path=(local:Analyse.DataPresent), ...}
  • 似乎也没有必要实现 INotifyPropertyChanged。您可以改为将您的类声明为静态:static class Analyse { ... }.
  • @Clemens 感谢对它进行排序的帮助。您能否为阅读这篇文章的其他人解释一下两者之间的区别,{Binding Path=(local:Analyse.DataPresent) 和 {Binding Source={x:Static local:Analyse.DataPresent}。
  • @Clemens 你是对的,它不需要继承,看起来有点奇怪,但这可能只是我需要阅读更多了解原因。

标签: c# wpf xaml data-binding


【解决方案1】:

Source 属性用于存储将用作备用绑定源的对象(默认情况下,绑定使用DataContext)。

<Button IsEnabled="{Binding Source={x:Static local:Analyze.DataPresent}}" />

因此,当您使用上面的代码时,Static 扩展提供了DataPresent 属性的当前值,并且该值存储在Source 属性中。在这种情况下,绑定使用一个装箱的常量值(truefalse)作为源。

<Button IsEnabled="{Binding Path=(local:Analyze.DataPresent)}" />

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

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

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

这意味着:

  1. Analyze 类可以是静态的,因为 INotifyPropertyChanged 不是必需的。
  2. 事件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 { };
}

有用的链接:

  1. Binding.Source Property
  2. Binding to static properties

【讨论】:

  • @Stephen Smith - 您应该将此标记为问题的答案。
  • 感谢你们两位的 cmets 和回复,他们都非常有帮助和有见地,希望他们能帮助其他人,而不仅仅是我!
  • 伙计们,这就是你要找的语法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-30
  • 2013-08-13
  • 2014-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多