静态属性绑定最初只能工作一次

时间:2015-01-07 05:40:44

标签: c# wpf

我在将WPF应用程序中的静态字符串属性绑定到textblock时遇到问题。 最初它正确设置了值,但我有一个更新值的方法,但更改不会反映在UI上。

我已经在线获取了StaticPropertyChanged代码,因此我的实现方式可能存在问题吗?

我确信这很简单,因为我对WPF很新。

感谢任何帮助!

有问题的财产:

private static string _isConnected = "Initial Value";

public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged;

public static string IsConnected
{
    get { return _isConnected; }
    set
    {
        _isConnected = value;
        if (StaticPropertyChanged != null)
            StaticPropertyChanged(null, new PropertyChangedEventArgs("IsConnected"));
    }
}

XAML:

<TextBlock Name="Test"
           Text="{Binding Source={x:Static status:Status.IsConnected}}">

谢谢:)

5 个答案:

答案 0 :(得分:1)

两件事:

  1. 您的自定义事件不会告诉UI该属性已更改。您必须实现INotifyPropertyChanged接口并引发PropertyChanged事件。这可以通过将处理程序注册到Status类中的StaticPropertyChanged和处理程序调用来完成 {1}} INotifyPropertyChanged

  2. 其次,如果您的Status类不是静态的,那么您不需要使用x:Static来绑定它。如果在DataContext中有您的Status类实例,则可以直接绑定到其静态属性,如

    PropertyChanged(null, new PropertyChangedEventArgs("IsConnected"));
  3. 此处假设您的 <TextBlock Name="Test" Text="{Binding Status.IsConnected}"/> 包含属性类型DataContext类的状态。

    如果Status类实例是您的Status,那么您可以直接将DataContext绑定为IsConnected

答案 1 :(得分:1)

在Window Resources中添加Status类资源,如下所示:

<Window.Resources>
    <local:Status x:Key="StatusManager"/>
</Window.Resources>

现在将IsConnected绑定到TextProperty,如下所示:

<TextBlock Name="Test"
       Text="{Binding Source={StaticResource StatusManager}, Path=IsConnected}"

答案 2 :(得分:1)

双向绑定需要使用Path中的Binding值。对于绑定到静态属性,它们需要非常特定的语法。在您的情况下,XAML应如下所示:

<TextBlock Name="Test"
           Text="{Binding Path=(status:Status.IsConnected), Mode=TwoWay}">

请注意路径周围使用括号。这表明解析器正确解释了类名。

您的代码隐藏是正确的。您已实现了一个StaticPropertyChanged事件,类似于实例版本PropertyChanged,以及WPF将用于绑定的事件。请注意,您也可以实现IsConnectedChanged事件。 WPF也会接受这一点。

最后,我注意到我读过的指南建议在可能和/或适当的情况下使用单例模式。虽然WPF现在支持绑定到静态属性,但仍然首选绑定到实际对象上的属性。

有关详细信息,请参阅此相关博文:WPF 4.5: Binding and change notification for static properties


修改

您没有询问如何在代码隐藏中创建绑定。但是,因为我在今天早些时候看到一个涉及在代码隐藏中设置绑定的另一个问题,所以我决定研究这对于静态属性是如何工作的。

对于实例属性,它很简单,因为您可以为Binding.Source属性指定一个对象。但对于静态属性,这是null(*)。相反,您必须通过Binding.Path属性指定属性:

Binding binding = new Binding();

binding.Path = new PropertyPath(typeof(Status).GetProperty("IsConnected");
binding.Mode = BindingMode.TwoWay;

这会将表示您绑定的属性的PropertyInfo对象传递给PropertyPath(object)构造函数重载。


(*)或者更确切地说,可以为空。绑定到静态属性时可以使用的一种hack是指定包含静态属性的类的实际实例。当然,对于static类,或者对于您没有碰巧使用的方便实例的类,您不能这样做。但是如果你这样做,那么你实际上可以绑定到静态属性,就像绑定到实例属性一样,指定包含静态属性的类的任何实例,以及静态属性的名称(就好像它是一个实例)属性)。

答案 3 :(得分:0)

我认为没有必要尝试这种方式

<TextBlock Name="Test"
           Text="{x:Static Member:namspacename.AppName.bool}">

答案 4 :(得分:0)

我无法以任何理由让静态绑定工作,但我能够使用Singleton正确绑定它。

public class Global : INotifyPropertyChanged
{
    private static  Global _instance = new Global();

    public static Global Instance
    {
        get { return _instance; }
    }

    private string _isConnected;

    public string IsConnected
    {
        get { return _isConnected; }
        set
        {
            _isConnected = value;
            OnPropertyChanged("IsConnected");
        }
    }


    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propName)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propName));
    }
}

和XAML:

        <TextBlock Name="Test"
                   DataContext="{x:Static status:Global.Instance}"
                   Text="{Binding Path=IsConnected}">