2013-09-16 129 views
0

我是WPF的新手,所以可能有一些基本的東西我在這裏不見了。我有一個看起來像這樣的應用程序:根據視圖模型中的屬性更改更新UI

<Window x:Class="MyApp.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Test Application" Height="647" Width="723" Background="#88B0FF"> 

    <DockPanel Name="MainDock"> 
     <Button DockPanel.Dock="Top" Margin="5,0,5,0" x:Name="PingButton" Click="PingButton_OnClick">Ping</Button> 
     <TextBox Text="{Binding Path=Output}" /> 
    </DockPanel> 
</Window> 

的隱藏代碼是這樣的:

public partial class MainWindow : Window 
{ 
    private Model _applicationModel = new Model(); 
    public Model ApplicationModel { 
     get { return _applicationModel; } 
     set { _applicationModel = value; } 
    } 

    public MainWindow() 
    { 
     InitializeComponent(); 

     this.DataContext = ApplicationModel; 
     ApplicationModel.Output = "Not clicked"; 
    } 

    private void PingButton_OnClick(object sender, RoutedEventArgs e) 
    { 
     ApplicationModel.Output = "Clicked"; 
    } 
} 

我有一個小的類稱爲模型,實現INotifyPropertyChanged。

public class Model : INotifyPropertyChanged 
{ 

    public string Output { get; set; } 

    public event PropertyChangedEventHandler PropertyChanged; 

    [NotifyPropertyChangedInvocator] 
    protected virtual void OnPropertyChanged(string propertyName) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

我運行此應用程序,文本框顯示文本「未點擊」。當我點擊按鈕時,我希望文本會發生改變。它不是。 「ApplicationModel」對象被更新,這反映在DataContext中;然而,我在OnPropertyChanged()方法中有一個斷點,它似乎永遠不會被調用。

我在做什麼錯?

回答

4

OnPropertyChanged()沒有被調用,因爲你沒有調用它。 沒有什麼特別的魔法可以自己連線到OnPropertyChanged,所以你需要自己動手。

具體來說,您應該修改Output屬性來調用它時,它改變了(並且它不會傷害到你的ApplicationModel財產做同樣的:

private string output; 
public string Output 
{ 
    get { return output; } 
    set 
    { 
     if (output != value) 
     { 
      output = value; 
      OnPropertyChanged("Output"); 
     } 
    } 
} 

如果你的目標.NET 4.5你。可以利用CallerMemberName attribute減少樣板代碼; This article解釋瞭如何做,那麼你就會有這樣的事情:

private string output; 
public string Output 
{ 
    get { return output; } 
    set { SetProperty(ref output, value); } 
} 

如果您使用以下.NET 4.0中,可以使用表達TRE如in this answer所述。

+0

Bah,我希望在這裏有一些反思魔術。在這裏減少樣板的最佳實踐? –

+0

@KeithRipley查看我的更新回答 –

+0

我看到了,這絕對適合我。 :-) –