2014-03-12 47 views
3

的價值我有一個ViewModelBase類,如下所示:的觀點是沒有得到通知時,靜態屬性更改

public class ViewModelBase : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 
    public void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    public static event PropertyChangedEventHandler GlobalPropertyChanged = delegate { }; 
    public static void OnGlobalPropertyChanged(string propertyName, Type className) 
    { 
     GlobalPropertyChanged(className,new PropertyChangedEventArgs(propertyName)); 
    } 
} 

現在,我還有一個視圖模型稱爲GroupViewModel它繼承ViewModelBase:

public class GroupViewModel : ViewModelBase 
{ 
    public GroupsViewModel() 
    { 
     CurrentGroup = new Group(); 
    } 

    private static Group _currentGroup; 
    public static Group CurrentGroup 
    { 
     get 
     { 
      return _currentGroup; 
     } 
     set 
     { 
      _currentGroup = value; 
      OnGlobalPropertyChanged("CurrentGroup", typeof(Group)); 
     } 
    } 
} 

現在Groups.xaml Page:

<Grid DataContext="{Binding CurrentGroup}"> 
    ..... 
    ..... 
    <TextBlock Text="{Binding GroupName, TargetNullValue=''}" /> 
    ..... 
    ..... 
</Grid> 

我有另一個叫做MainWindowViewModel的ViewModel,I t RY到CurrentGroup保存到數據庫如下面的代碼,然後我設置CurrentGroup = new Group();但Group.xaml TextBox的文本沒有被清除:

Group group = GroupViewModel.CurrentGroup; 
db.Groups.Add(group); 
db.SaveChanges(); 
GroupViewModel.CurrentGroup = new Group(); 

更新:

如果我使用GroupsViewModel下面的代碼,產量如預期。我的意思是更新靜態屬性更改時視圖。

public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged 
     = delegate { }; 
private static void NotifyStaticPropertyChanged(string propertyName) 
{ 
    StaticPropertyChanged(null, new PropertyChangedEventArgs(propertyName)); 
} 

如果我使用的是在ViewModelBase相同的代碼(請注意,GroupsViewModel繼承ViewModelBase),那麼不更新視圖時的靜態屬性的變化值。在這種情況下,我還將NotifyStaticPropertyChanged標記爲public,以避免編譯時錯誤,如有關保護級別的錯誤。

+0

嘗試提供的解決方案[此處](http://10rem.net/blog/2011/11/29/wpf-45-binding-and-change-notification-for-static-properties)。 –

+0

必須提高viewmodel的屬性更改事件,靜態成員不是實例的成員。 – Silvermind

+0

@RohitVats好的,我會嘗試一下,讓你知道。 – Vishal

回答

10

Static PropertyChanged你必須像這樣在你的類創建通用的靜態事件:

public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged 
     = delegate { }; 
private static void NotifyStaticPropertyChanged(string propertyName) 
{ 
    StaticPropertyChanged(null, new PropertyChangedEventArgs(propertyName)); 
} 

,你得叫喜歡你所使用的實例屬性:

NotifyStaticPropertyChanged("CurrentGroup"); 

但主要的缺點是在你綁定的XAML中 -

你將在命名空間,類和屬性周圍使用括號 ,因爲WPF綁定引擎將路徑解析爲ClassName.PropertyName 而不是PropertyName.PropertyName。

所以,這將是這樣的:

<Grid DataContext="{Binding Path=(local:GroupViewModel.CurrentGroup)}"> 
    ..... 
    ..... 
    <TextBlock Text="{Binding GroupName, TargetNullValue=''}" /> 
    ..... 
    ..... 
</Grid> 

來源這裏INPC for static properties


UPDATE

如果我使用的是在ViewModelBase相同的代碼(請注意, GroupsViewModel繼承ViewModelBase),那麼不更新視圖時的靜態屬性更改 值。

StaticPropertyChangedEvent必須在相同的類,其中屬性駐留。它不會像傳統的INotifyPropertyChanged那樣工作。

我沒有任何MSDN文檔來聲明,但我通過調整事件代碼來驗證XAML是否掛鉤到來自XAML的StaticPropertyChangedEvent

更換事件代碼,這一點,你可以看到自己:

private static event EventHandler<PropertyChangedEventArgs> staticPC 
                = delegate { }; 
public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged 
{ 
    add { staticPC += value; } 
    remove { staticPC -= value; } 
} 
protected static void NotifyStaticPropertyChanged(string propertyName) 
{ 
    staticPC(null, new PropertyChangedEventArgs(propertyName)); 
} 

將斷點上添加,你會看到,因爲WPF會被打到綁定引擎內部鉤它來聽靜態屬性改變事件。

但是,只要將它移動到基類ViewModelBase,斷點就不會被擊中。因爲WPF沒有掛鉤它,所以任何屬性更改都不會更新UI。

+0

我試圖使用上面的例子,但在XAML中我得到以下錯誤:'嵌套類型不支持:GroupViewModel.CurrentGroup'。另外,在我的問題中,我錯過了一些信息。我的頁面的DataContext是本地的:GroupViewModel,然後你可以在qustion中看到Grid的DataContext設置爲CurrentGroup,TextBox的文本綁定到GroupName。你在回答中提到的是不是同一件事? – Vishal

+1

您正在將靜態與實例屬性混淆。 DataContext被設置爲'GroupViewModel'的一個實例,但是屬性是靜態的,所以你不能使用對XAML有效的實例對象來訪問它。你必須像我在我更新的答案中那樣設置DataContext。如果Grid中有其他項目,只需將該DataContext移動到TextBlock上即可完成。 –

+0

現在我沒有得到任何錯誤,但行爲仍然是相同的。我的意思是我的文本框仍然沒有清理。 – Vishal

1

無論何時您想要更新特定數據類型的屬性更改,都需要在該數據類型中實現INotifyPropertyChanged接口。這意味着如果您想更新視圖模型的屬性更改,在您的情況下更改爲CurrentGroup對象,則需要在視圖模型中實現INotifyPropertyChanged接口

但是,它好像你實際上要更新已作出CurrentGroup類(以清除它們)屬性的變化,所以在這種情況下,你需要實現INotifyPropertyChanged接口在你的CurrentGroup類中也是如此。我相信@Silvermind的意思是您需要提高與實例關聯的事件。

相關問題