自定义类的PropertyChanged始终为null

时间:2016-09-13 02:16:05

标签: c# wpf data-binding

我遇到INotifyPropertyChanged和绑定问题,我在这里看了十几个问题,但问题仍然存在。

我的XAML代码:

<Window x:Class="DAA.IST.ChoosePC.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:DAA.IST.ChoosePC"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <local:Question x:Key="ExpertSystem" Text="question"/>
</Window.Resources>
<Grid DataContext="{StaticResource ExpertSystem}">
    <Label x:Name="Description" Content="Определение опимальной конфигурации ПК" HorizontalAlignment="Left" Margin="100,30,0,0" VerticalAlignment="Top"/>
    <Button x:Name="button" Content="" HorizontalAlignment="Left" Margin="204,167,0,0" VerticalAlignment="Top" Width="75" Click="button_Click"/>
    <Button x:Name="button1" Content="" HorizontalAlignment="Left" Margin="284,167,0,0" VerticalAlignment="Top" Width="75" Click="button1_Click"/>
    <Label x:Name="QuestionLable" Content="{Binding Text}" HorizontalAlignment="Left" Margin="100,70,0,0" VerticalAlignment="Top"/>
    <Label x:Name="Result" Content="" HorizontalAlignment="Left" Margin="100,210,0,0" VerticalAlignment="Top"/>

</Grid>

我在这里列出完整的代码,因为我真的不知道有问题,对不起。主窗口代码:

public partial class MainWindow : Window
{
    public static IQuestion Question;

    public MainWindow()
    {
        InitializeComponent();
        Question = new Question
        {
            Text = "question",
            Answers = new List<IAnswer>
                      {
                          new Answer {Text = "answer", NextQuestionNumber = 0},
                          new Answer {Text = "answer1", NextQuestionNumber = 0}
                      }
        };
        DataContext = Question;
    }

    private void button_Click(object sender, RoutedEventArgs e)
    {
        Question.Answer(0);
    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        Question.Answer(1);
    }
}

Question代码,此类实现INotifyPropertyChanged

public class Question : IQuestion, INotifyPropertyChanged
{
    private string _text;

    public string Text
    {
        get { return _text; }
        set
        {
            _text = value;
            OnPropertyChanged("Text");
        }
    }


    public IList<IAnswer> Answers { get; set; }

    public void Answer(int number)
    {
        MainWindow.Question.Answers[number].Number = number;
        MainWindow.Question.Answers[number].SetNextQuestion();
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

请帮助我,确定我想念或不知道。如果有人可以给我建议改变IList<IAnswer> Answers,我会感谢他^^

2 个答案:

答案 0 :(得分:1)

首先,在问题类中引用MainWindow是不好的做法。 您应该在此上下文中使用命令,即您应该在DataContext中定义一个命令(此处有问题)并将该命令绑定到您的两个Button的Command属性。

例如:

Class Question : INotifyPropertyChanged, IQuestion
{
  public ICommand ButtonClickCommand { get; set;}

  public Question()
  {
    //Bind ButtonClickCommand to Event Handler/ A Method
    ButtonClickCommand = new DelegateCommand(EventHandlerName);
  }
  public void EventHandlerName()
  {
  }
}

此外,在类中使用私有_answers字段并从Setter of Answers属性中引发 OnPropertyChanged 事件,以在通知机制中使用此列表,即

public IList<IAnswer> Answers { 
  get { return _answers }
  set { _nswers = value;
  OnPropertyChanged("Answers");

}

并且,您已经提到要想更改标签和按钮的内容。但是要更改标签和按钮的内容,您需要绑定内容&#39;这些控件也属于Question类中的Properties。到目前为止,我在XAML中看不到任何约束力。

答案 1 :(得分:-1)

最后,我发现了自己的错误。我应该更改属性,而不是创建新实例。如果我创建一个新值,旧值保持不变。它以某种方式与引用类型相关联。

MainWindow.Question.Text = "question";
MainWindow.Question.Answers[0].Text = "answer0";
MainWindow.Question.Answers[0].NextQuestionNumber = number0;
MainWindow.Question.Answers[1].Text = "answer1";
MainWindow.Question.Answers[1].NextQuestionNumber = number1;