-1

我是 WPF 的新手,所以这里可能缺少一些基本的东西。我有一个看起来像这样的应用程序:

<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";
    }
}

我有一个名为 Model 的小类,它实现了 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

1 回答 1

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属性来减少样板代码;本文介绍了如何执行此操作。然后你会有这样的东西:

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

如果您使用的是 .NET 4.0 或更低版本,则可以使用表达式树,如本答案中所述。

于 2013-09-16T19:03:51.690 回答