2009-11-06 72 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