Search code examples
c#wpfdata-binding

Programme doesn't bind a variable in mode two way


I'm writing my first WPF app using MVVM. This app is intended for musical ear training. In the model, I declared a variable, which stores the content of combobox, in which the user sends an answer to what sound he heard. I defined in the constructor initial value of this variable on "--Select a sound--". I also create a corresponding property in the view model. After start app in combobox is showing this value, but after sending this variable remains unchanged (I check it by using breakpoint in VS). Why it happens? Does my binding is incorrect?

Declaration and definition of values in the model:

private string choosenSound;

public string ChoosenSound
{
    get { return choosenSound; }
    set { choosenSound = value; }
}

public SoundsModel()
{
     this.valueOfCorrectAnswers = 0;
     this.valueOfIncorrectAnswers = 0;
     this.choosenSound = "--Select a sound--";
     this.correctSound = String.Empty;
}

In view model:

public string ChoosenSound
{
      get { return model.ChoosenSound; }
      set { OnPropertyChanged(nameof(ChoosenSound)); }
}

Command, which checks if the user sent the correct answer:

public ICommand NextSound
{
     get
     {
        if (nextSound == null)
        {
           nextSound = new RelayCommand(
            (object o) =>
            {
                if (CorrectSound != ChoosenSound) // Here I set a breakpoint
                MessageBox.Show("Incorrect answer. That was sound " + CorrectSound);

                model.Check();

                OnPropertyChanged(nameof(ValueOfCorrectAnswers));
                OnPropertyChanged(nameof(ValueOfIncorrectAnswers));
                OnPropertyChanged(nameof(ChoosenSound));

                model.RndSound();
                OnPropertyChanged(nameof(CorrectSound));

                model.PlaySound();
              },
              (object o) =>
              {
                  return model.ChoosenSound != null;
              });
             }

              return nextSound;
            }
        }

Method Check() in model class:

public void Check()
{
    choosenAnswers.Add(choosenSound);
    correctAnswers.Add(correctSound);

    if (choosenSound == correctSound)
       ValueOfCorrectAnswers++;
            

    else ValueOfIncorrectAnswers++;

   choosenSound = "--Select a sound--";
}

Binding in XAML code:

d:DataContext="{d:DesignInstance Type=vm:SoundsViewModel}"

<Window.DataContext>
        <vm:SoundsViewModel x:Name="viewModel" />
</Window.DataContext>

<ComboBox x:Name="SoundComboBox" Grid.Column="1" Width="200" Height="30" 
 IsEditable="True" Text="{Binding Path=ChoosenSound, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
 StaysOpenOnEdit="True">
    <ComboBoxItem x:Name="soundC"  Content="C" />  
    <ComboBoxItem x:Name="soundCis" Content="C#" />
    <ComboBoxItem x:Name="soundD"  Content="D" />
    <ComboBoxItem x:Name="soundDis"  Content="D#" />                                                              <ComboBoxItem x:Name="soundE"  Content="E" /> 
    <ComboBoxItem x:Name="soundF"  Content="F" />
    <ComboBoxItem x:Name="soundFis"  Content="F#" />
    <ComboBoxItem x:Name="soundG"  Content="G" />
    <ComboBoxItem x:Name="soundGis"  Content="G#" />
    <ComboBoxItem x:Name="soundA" Content="A" />
    <ComboBoxItem x:Name="soundBb" Content="Bb" />
    <ComboBoxItem x:Name="soundB"  Content="B" />
</ComboBox>

I would be very grateful for your help.


Solution

  • you forgot to store value in view model setter setter:

    public string ChoosenSound
    {
        get { return model.ChoosenSound; }
        set 
        { 
             model.ChoosenSound = value; // was missing
             OnPropertyChanged(nameof(ChoosenSound)); 
        }
    }