2009-11-06 42 views
4

我有一个布尔静态属性称为CanSeePhotos一类,这应该控制我的DataTemplate图片的可视性。 出于调试的目的我“CanSeePhotos”结合在DataTemplate中文本块。WPF - DataTemplate的结合静态成员

我想要做的是:

  1. 的InitializeComponent()的基础上登录的用户
  2. 加载数据
  3. 集CanSeePhotos并适当地表现出来

我的问题是,如果我设置CanSeePhotos =真后的InitializeComponent(),该数据仍然与CanSeePhotos假所示(如果我这样做,它的工作原理确定之前)。这是为什么?我怎样才能解决这个问题,以便我可以在加载数据之前的任何时刻设置数值?

这里是我如何绑定到我的DataTemplate静态变量:

<TextBlock Text="{Binding Source={x:Static DAL:LoggedInUser.CanSeePhotos}, Mode=OneWay}"/> 

而这里的是loggedInUser类:

public class LoggedInUser 
{ 
    public static bool CanSeePhotos { get; set; } 
} 

编辑: 如果我绑定控件的知名度直静态属性,它会显示/折叠根据属性的值:

Visibility="{Binding Source={x:Static DAL:LoggedInUser.CanSeePhotos}, Converter={StaticResource BooleanToVisibilityConverter}}" 

但我需要使用一个DataTrigger像这样:

<DataTrigger Binding="{Binding Source={x:Static DAL:LoggedInUser.CanSeePhotos}}" Value="true"> 
    <Setter TargetName="icon" Property="Source" Value="{Binding Photo}"/> 
</DataTrigger> 

在二传手从来没有得到,如果属性为true设置上面的情况。

什么给?

回答

7

有三个方面的考虑这里:

代价1:该物业有没有变化通知

一些数据绑定可能在InitializeComponent()调用过程中进行评估,和其他人稍后求。您正在请求在InitializeComponent()已经返回之后设置CanSeePhotos的能力。如果没有任何变化通知,任何有约束力的InitializeComponent(在评估)将原来的值并不会更新。之后评估的任何绑定(例如DataBind优先级)都将具有新值。为了使这项工作在所有情况下都需要某种更改通知。

使用与声明的.NET Framework的属性“{获取;集;}”将无法工作,因为酒店有没有一种机制,如果它的值改为通知任何人。实际上有两种非常偷偷摸摸的方式从标准的.NET Framework属性(MarshalByRefObject和IL重写)中获取通知,但它们对于您的情况太复杂了。

考虑2:该物业是静态

NET Framework有几个属性更改通知机制(DependencyProperty的,INotifyPropertyChanged的,等等),但没有内置机制支持静态属性更改通知。因此,如果不创建用于更改信号的新机制(例如,您可能有一个包装该属性的对象),则无法使用此属性。

考虑3:DataTriggers共享一个绑定

当设置能见度一个新的绑定,每次你正在建设,所以它得到LoggedInUser.CanSeePhotos的最新值。

创建DataTrigger时,WPF会在加载触发器时构造一个Binding,并将其用于每个对象。这个绑定是在包含DataTrigger的资源字典被加载时构建的,这可能是在应用程序启动时,所以它总是会获得CanSeePhotos的默认值。这是因为Source =将一个实际对象分配到绑定中(它的计算不是延迟的)。因此,每个绑定都是通过Source = true或Source = false构建的。

推荐的解决方案

使用带有一个DependencyProperty为DependencyObject和静态属性引用它,就像这样:

public class LoggedInUser : DependencyObject 
{ 
    // Singleton pattern (Expose a single shared instance, prevent creating additional instances) 
    public static readonly LoggedInUser Instance = new LoggedInUser(); 
    private LoggedInUser() { } 

    // Create a DependencyProperty 'CanSeePhotos' 
    public bool CanSeePhotos { get { return (bool)GetValue(CanSeePhotosProperty); } set { SetValue(CanSeePhotosProperty, value); } } 
    public static readonly DependencyProperty CanSeePhotosProperty = DependencyProperty.Register("CanSeePhotos", typeof(bool), typeof(LoggedInUser), new UIPropertyMetadata()); 

} 

该类总会有一个实例,该实例将作为LoggedInUser.Instance。所以它有点像静态类。所不同的是,LoggedInUser.Instance有一个DependencyProperty,所​​以当你修改属性时它可以通知任何感兴趣的人。 WPF的绑定将注册这个通知,所以你的UI将被更新。

上面的代码将在XAML中使用这样的:

Visibility="{Binding CanSeePhotos, Source={x:Static LoggedInUser.Instance}, Converter=... 

在你的后台代码,如果你需要访问CanSeePhotos这将是,例如:

LoggedInUser.Instance.CanSeePhotos = true; 
+0

喜雷,我了解依赖属性,但不想使用它们,因为在第一次检索数据后,CanSeehotos永远不会被更改。抛出我的是,将对象的可见性绑定到DataTemplate中的静态属性可以正常工作,但它在DataTemplate的DataTrigger中不起作用。感谢您的回答。我会尝试。 – 2009-11-07 18:21:32

+0

感谢您澄清您的问题。我在答案中添加了一个新的“问题3”,以澄清DataTrigger无法正常工作的原因,并在“问题1”中解释了为什么您需要更改通知。希望这可以帮助。 – 2009-11-07 19:15:37

+0

+1,但是在这里你确实不需要DependencyProperty,恕我直言,实现INotifyPropertyChanged更好 – 2009-11-07 19:19:35