2009-02-11 161 views
2

所以我現在正在學習WPF,並且希望在bool值和MenuItem之間是否啓用一個簡單的數據綁定。WPF數據綁定IsEnabled屬性

我已經編寫這樣的:

<MenuItem Name="miSaveFile" Header="Save" Click="miSaveFile_Click" 
IsEnabled="{Binding}" /> 

而在.cs文件我設置:

miSaveFile.DataContext = dataChanged; 

出於某種原因,MenuItem似乎並不正確反映狀態dataChanged。

我錯過了什麼?

回答

4

你最好綁定到一個對象,而不是原始類型。該對象通常被稱爲您的視圖的「模型」。

WPF對模型(或通常是視圖模型)使用INotifyPropertyChanged接口來通知視圖模型已更改狀態。

因此,您首先需要將數據類定義爲實現INotifyPropertyChanged接口的模型,並在屬性發生更改時觸發PropertyChanged事件。

當你設置一個綁定時,你有5個關於綁定的主要元素擔心。該綁定具有源對象,源對象上的源路徑,目標對象,目標對象上的目標屬性以及可選的轉換器。

如果不指定源,則默認爲綁定設置的控件的DataContext。還有其他選項可用於設置源。 Here是一篇關於設置源代碼的Microsoft文章。然後可以設置屬性的路徑以從綁定的源中取出。在你的情況下,源是一個布爾值,並且沒有路徑,因爲綁定正在使用整個源對象。

目標始終是您設置綁定的控件,而目標屬性是您綁定到的此控件的屬性。在這種情況下,MenuItem和IsEnabled。

轉換器可以選擇將源值轉換爲與目標屬性兼容的值。您可以將任何對象用於實現IValueConverter或IMultiValueConverter(用於MutliBindings)的轉換器。

就你而言,我會先創建一個實現INotifyPropertyChanged的模型。接下來,我將菜單的DataContext分配給模型的一個實例。然後我會設置綁定到:

IsEnabled="{Binding Path=EnableFlag}" 

(其中EnableFlag是要菜單綁定到模型中的布爾屬性)

如果設置了INotifyPropertyChanged接口正確,菜單項將在模型上更改此屬性時啓用/禁用。

1

UI如何知道dataChanged變量何時實際更改?

我通常綁定到一個對象的屬性,並讓該類實現INotifyPropertyChanged。然後,只要PropertyChanged事件被調用,UI就會「自動」更新。

所以我會

<MenuItem Name="miSaveFile" Header="Save" Click="miSaveFile_Click" 
IsEnabled="{Binding DataChanged}"</MenuItem> 

,然後設置miSaveFile.DataContext = myObject.DataChanged (myObject的可能是這個,如果你正在使用的代碼隱藏)

編輯:我只是做了一個快速測試。如果將數據上下文直接設置爲DataChanged屬性,則不會添加對所有者對象上的PropertyChanged事件的訂閱。但我建議的解決方案是有效的。

+0

「?如何在UI知道什麼時候dataChanged變量實際上已經改變了」好問題。現在我仍然在Data_Binding-Is-Voodoo階段:) – 2009-02-11 14:03:08

2

對於MenuItem,使用Command模型而不是Click和IsEnabled屬性會不會更好?

後InitialiseComponent():

this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Save, fileSaveExecuted, fileSaveCanExecute)); 

其他方法:

/* here is where you set e.CanExecute true for enabled: */ 
    private void fileSaveCanExecute(object x, CanExecuteRoutedCommandEventArgs e)) { e.CanExecute = ...; e.Handled = true; } 
/* here is where you act on the command: */ 
    private void fileSaveExecuted(object sender, ExecutedRoutedEventArgs e) { ... } 

XAML:

<MenuItem Header="_Save" Command="Save"/>