静态 属性 绑定最初只工作一次
Static property bind only works once initially
我在将静态字符串 属性 绑定到 WPF 应用程序中的文本块时遇到问题。
最初它正确设置了值,但我有一个更新值的方法,但更改没有反映在 UI.
我已经在网上获取了静态属性更改的代码,所以我的实现方式可能存在问题?
我确定我缺少的是一些简单的东西,因为我对 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}}">
谢谢:)
我认为没有必要尝试这种方式
<TextBlock Name="Test"
Text="{x:Static Member:namspacename.AppName.bool}">
两件事:
您的自定义事件不会告诉 UI 属性 已更改。您将必须实现 INotifyPropertyChanged
接口并引发 PropertyChanged
事件。这可以通过将处理程序注册到 Status
class 中的 StaticPropertyChanged 并从处理程序调用中完成
PropertyChanged(null, new PropertyChangedEventArgs("IsConnected"));
的 INotifyPropertyChanged
其次,如果您的 Status class 不是静态的,那么您不需要使用 x:Static 来绑定它。如果你的 DataContext 中有 Status class 实例,你可以直接绑定到它的静态 属性 like
<TextBlock Name="Test" Text="{Binding Status.IsConnected}"/>
这里假设您的 DataContext
包含 属性 类型 Status
class.
的状态
如果 Status class 实例是您的 DataContext
那么您可以直接将 IsConnected
绑定为 <TextBlock Name="Test" Text="{Binding IsConnected}"/>
无论出于何种原因,我都无法使静态绑定正常工作,但我能够使用 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}">
在 Window 资源中添加状态 class 资源,如下所示:
<Window.Resources>
<local:Status x:Key="StatusManager"/>
</Window.Resources>
现在将您的 IsConnected 绑定到 TextProperty,如下所示:
<TextBlock Name="Test"
Text="{Binding Source={StaticResource StatusManager}, Path=IsConnected}"
双向绑定需要使用 Binding
中的 Path
值。为了绑定到静态属性,它们需要非常特定的语法。在您的情况下,XAML 应该如下所示:
<TextBlock Name="Test"
Text="{Binding Path=(status:Status.IsConnected), Mode=TwoWay}">
请注意路径两边的括号。这指示解析器正确解释 class 名称。
您的代码隐藏是正确的。您已经实现了一个 StaticPropertyChanged
事件,类似于实例版本 PropertyChanged
,WPF 将使用哪个事件进行绑定。请注意,您也可以改为实施 IsConnectedChanged
事件。 WPF 也会接受这一点。
最后我注意到,我读过的指南建议尽可能 and/or 使用单例模式。虽然 WPF 现在支持绑定到静态属性,但仍然首选绑定到实际对象上的 属性。
有关详细信息,请参阅此相关博客 post: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)
构造函数重载。
(*) 或者更确切地说,它 可以 为空。绑定到静态属性时可以使用的一种技巧是指定包含静态 属性 的 class 的实际实例。当然,您不能对 static
classes 或 classes 执行此操作,因为您碰巧没有可用的方便实例。但如果这样做,那么您实际上可以绑定到静态 属性,就像绑定到实例 属性 一样,指定包含静态 属性 的 class 的任何实例],以及静态的名称 属性(就好像它是一个实例 属性)。
我在将静态字符串 属性 绑定到 WPF 应用程序中的文本块时遇到问题。 最初它正确设置了值,但我有一个更新值的方法,但更改没有反映在 UI.
我已经在网上获取了静态属性更改的代码,所以我的实现方式可能存在问题?
我确定我缺少的是一些简单的东西,因为我对 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}}">
谢谢:)
我认为没有必要尝试这种方式
<TextBlock Name="Test"
Text="{x:Static Member:namspacename.AppName.bool}">
两件事:
您的自定义事件不会告诉 UI 属性 已更改。您将必须实现
INotifyPropertyChanged
接口并引发PropertyChanged
事件。这可以通过将处理程序注册到Status
class 中的 StaticPropertyChanged 并从处理程序调用中完成PropertyChanged(null, new PropertyChangedEventArgs("IsConnected"));
的 INotifyPropertyChanged其次,如果您的 Status class 不是静态的,那么您不需要使用 x:Static 来绑定它。如果你的 DataContext 中有 Status class 实例,你可以直接绑定到它的静态 属性 like
<TextBlock Name="Test" Text="{Binding Status.IsConnected}"/>
这里假设您的 DataContext
包含 属性 类型 Status
class.
如果 Status class 实例是您的 DataContext
那么您可以直接将 IsConnected
绑定为 <TextBlock Name="Test" Text="{Binding IsConnected}"/>
无论出于何种原因,我都无法使静态绑定正常工作,但我能够使用 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}">
在 Window 资源中添加状态 class 资源,如下所示:
<Window.Resources>
<local:Status x:Key="StatusManager"/>
</Window.Resources>
现在将您的 IsConnected 绑定到 TextProperty,如下所示:
<TextBlock Name="Test"
Text="{Binding Source={StaticResource StatusManager}, Path=IsConnected}"
双向绑定需要使用 Binding
中的 Path
值。为了绑定到静态属性,它们需要非常特定的语法。在您的情况下,XAML 应该如下所示:
<TextBlock Name="Test"
Text="{Binding Path=(status:Status.IsConnected), Mode=TwoWay}">
请注意路径两边的括号。这指示解析器正确解释 class 名称。
您的代码隐藏是正确的。您已经实现了一个 StaticPropertyChanged
事件,类似于实例版本 PropertyChanged
,WPF 将使用哪个事件进行绑定。请注意,您也可以改为实施 IsConnectedChanged
事件。 WPF 也会接受这一点。
最后我注意到,我读过的指南建议尽可能 and/or 使用单例模式。虽然 WPF 现在支持绑定到静态属性,但仍然首选绑定到实际对象上的 属性。
有关详细信息,请参阅此相关博客 post: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)
构造函数重载。
(*) 或者更确切地说,它 可以 为空。绑定到静态属性时可以使用的一种技巧是指定包含静态 属性 的 class 的实际实例。当然,您不能对 static
classes 或 classes 执行此操作,因为您碰巧没有可用的方便实例。但如果这样做,那么您实际上可以绑定到静态 属性,就像绑定到实例 属性 一样,指定包含静态 属性 的 class 的任何实例],以及静态的名称 属性(就好像它是一个实例 属性)。