Moses Aprico
Moses Aprico

Reputation: 2121

Can't get the view updated, even though the model is already updated

This is my XAML

<Window x:Class="NoteBox.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:NoteBox"
    Title="NoteBox">
<Window.Resources>
    <local:NoteOctaveConverter x:Key="NoteOctaveConverter"/>
    <local:DottedNoteConverter x:Key="DottedNoteConverter"/>
    <local:NoteEnumerationConverter x:Key="NoteEnumerationConverter"/>
    <local:NoteAccidentalConverter x:Key="NoteAccidentalConverter"/>
</Window.Resources>
<Window.InputBindings>
    <KeyBinding Key="OemPeriod" Command="{Binding KeyboardHotkeyCommand}" CommandParameter="Blank"/>
    <KeyBinding Key="D0" Command="{Binding KeyboardHotkeyCommand}" CommandParameter="Rest"/>
    <KeyBinding Key="D1" Command="{Binding KeyboardHotkeyCommand}" CommandParameter="N1"/>
    <KeyBinding Key="D2" Command="{Binding KeyboardHotkeyCommand}" CommandParameter="N2"/>
    <KeyBinding Key="D3" Command="{Binding KeyboardHotkeyCommand}" CommandParameter="N3"/>
    <KeyBinding Key="D4" Command="{Binding KeyboardHotkeyCommand}" CommandParameter="N4"/>
    <KeyBinding Key="D5" Command="{Binding KeyboardHotkeyCommand}" CommandParameter="N5"/>
    <KeyBinding Key="D6" Command="{Binding KeyboardHotkeyCommand}" CommandParameter="N6"/>
    <KeyBinding Key="D7" Command="{Binding KeyboardHotkeyCommand}" CommandParameter="N7"/>
</Window.InputBindings>

<Grid x:Name="grid" Background="GreenYellow">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="20"/>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="20"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="20"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="20"/>
    </Grid.RowDefinitions>

    <TextBlock Grid.Column="0" Grid.Row="1"
               Text="{Binding Path=MusicalNotation.Accidental, Converter={StaticResource NoteAccidentalConverter}, Mode=OneWay}" 
               FontSize="15" FontFamily="CourierNew" 
               HorizontalAlignment="Center" VerticalAlignment="Center"/>
    <TextBlock Grid.Column="1" Grid.Row="1" 
               Text="{Binding Path=MusicalNotation.Note, Converter={StaticResource NoteEnumerationConverter}, Mode=OneWay}" 
               FontSize="15" FontFamily="CourierNew" 
               HorizontalAlignment="Center" VerticalAlignment="Center"/>
    <ListBox Grid.Column="1" Grid.Row="0"
             BorderBrush="Transparent" Background="Transparent"
             ItemsSource="{Binding Path=MusicalNotation.Octave, Converter={StaticResource NoteOctaveConverter}, ConverterParameter=TOP, Mode=OneWay}"
             HorizontalAlignment="Center" VerticalAlignment="Center">
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel IsItemsHost="True"/>
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
    </ListBox>
    <ListBox Grid.Column="1" Grid.Row="2"
             BorderBrush="Transparent" Background="Transparent"
             ItemsSource="{Binding Path=MusicalNotation.Octave, Converter={StaticResource NoteOctaveConverter}, ConverterParameter=BOT, Mode=OneWay}"
             HorizontalAlignment="Center" VerticalAlignment="Center">
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel IsItemsHost="True"/>
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
    </ListBox>
    <ListBox Grid.Column="2" Grid.Row="1"
             BorderBrush="Transparent" Background="Transparent"
             ItemsSource="{Binding Path=MusicalNotation.Dot, Converter={StaticResource DottedNoteConverter}, Mode=OneWay}"
             HorizontalAlignment="Center" VerticalAlignment="Center">
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel IsItemsHost="True"/>
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
    </ListBox>
</Grid>

This is XAML.CS

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new NoteBoxViewModel();
    }
}

And this is my ModelView

public class NoteBoxViewModel
{
    public MusicalNotation MusicalNotation { get; set; }
    public ICommand KeyboardHotkeyCommand { get; private set; }
    public bool IsSelected { get; set; }

    public NoteBoxViewModel()
    {
        MusicalNotation = new MusicalNotation();
        KeyboardHotkeyCommand = new KeyboardHotkeyCommand(this);
        IsSelected = true;

        //Initialization testing
        MusicalNotation.Note = Notes.N1;
        MusicalNotation.Dot = 1;
        MusicalNotation.Octave = -2;
        MusicalNotation.Accidental = Accidentals.Flattened;
    }
}

Even though the model is updated, but the View isn't when input using the InputBindings. Input detection is working properly and the model is updated properly. The converter also works well, otherwise, the initialization testing won't visualize anything too. (The data from initialization testing showed perfectly).

My guess is somewhere on the binding. But I can't find any.

Thanks.

Note

Upvotes: 0

Views: 46

Answers (1)

BRAHIM Kamel
BRAHIM Kamel

Reputation: 13755

you have to Implement the INotifyPropertyChanged

 public class NoteBoxViewModel:INotifyPropertyChanged
    {
   //here an example 
        public MusicalNotation MusicalNotation
    { 
     get{
         return _musicalNotation;
        } 
      set{ _musicalNotation =Value;
             // by using [CallerMemberName]  you  don't  need to pass the name of the method  (this only available in .net 4.5 )
            NotifyPropertyChanged();}
          }        

        public NoteBoxViewModel()
        {
            MusicalNotation = new MusicalNotation();
            KeyboardHotkeyCommand = new KeyboardHotkeyCommand(this);
            IsSelected = true;

            MusicalNotation.Note = Notes.N1;
            MusicalNotation.Dot = 1;
            MusicalNotation.Octave = -2;
            MusicalNotation.Accidental = Accidentals.Flattened;


        }

 public event PropertyChangedEventHandler PropertyChanged;

 private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

Upvotes: 1

Related Questions