C
C#2mo ago
kianyuen

ViewModel Command ran when I debugged, but the View is not updated

This is my ViewModel:
public class MainViewModel : ViewModelBase
{
private ViewModelBase _currentChildView;
private string _title;

public ViewModelBase CurrentChildView
{
get
{
return _currentChildView;
}
set
{
_currentChildView = value;
OnPropertyChanged(nameof(CurrentChildView));
}
}
public string Title
{
get => _title;
set
{
_title = value;
OnPropertyChanged(nameof(Title));
}
}

// Commands for user interactions
public ICommand ShowBloodPressureViewCommand { get; }
public ICommand ShowBMIViewCommand { get; }
public ICommand ShowHeightWeightViewCommand { get; }


public MainViewModel()
{
ShowBloodPressureViewCommand = new RelayCommand(ExecuteShowBloodPressureViewCommand);
ShowBMIViewCommand = new RelayCommand(ExecuteShowBMIViewCommand);
ShowHeightWeightViewCommand = new RelayCommand(ExecuteShowHeightWeightViewCommand);

ExecuteShowBloodPressureViewCommand(null);
}

private void ExecuteShowHeightWeightViewCommand(object obj)
{
CurrentChildView = new HeightWeightViewModel();
Title = "Height Weight";

}

private void ExecuteShowBMIViewCommand(object obj)
{
CurrentChildView = new BMIViewModel();
Title = "BMI";
}

private void ExecuteShowBloodPressureViewCommand(object obj)
{
CurrentChildView = new BloodPressureViewModel();
Title = "Blood Pressure";
}
}
public class MainViewModel : ViewModelBase
{
private ViewModelBase _currentChildView;
private string _title;

public ViewModelBase CurrentChildView
{
get
{
return _currentChildView;
}
set
{
_currentChildView = value;
OnPropertyChanged(nameof(CurrentChildView));
}
}
public string Title
{
get => _title;
set
{
_title = value;
OnPropertyChanged(nameof(Title));
}
}

// Commands for user interactions
public ICommand ShowBloodPressureViewCommand { get; }
public ICommand ShowBMIViewCommand { get; }
public ICommand ShowHeightWeightViewCommand { get; }


public MainViewModel()
{
ShowBloodPressureViewCommand = new RelayCommand(ExecuteShowBloodPressureViewCommand);
ShowBMIViewCommand = new RelayCommand(ExecuteShowBMIViewCommand);
ShowHeightWeightViewCommand = new RelayCommand(ExecuteShowHeightWeightViewCommand);

ExecuteShowBloodPressureViewCommand(null);
}

private void ExecuteShowHeightWeightViewCommand(object obj)
{
CurrentChildView = new HeightWeightViewModel();
Title = "Height Weight";

}

private void ExecuteShowBMIViewCommand(object obj)
{
CurrentChildView = new BMIViewModel();
Title = "BMI";
}

private void ExecuteShowBloodPressureViewCommand(object obj)
{
CurrentChildView = new BloodPressureViewModel();
Title = "Blood Pressure";
}
}
When initialized, ExecuteShowBloodPressureViewCommand ran normally, but when I use UI to run other commands, the Execute function still ran, but the View doesn't update.
7 Replies
Klarth
Klarth2mo ago
Need more specifics. What is ViewModelBase? Is it your own MVVM framework? A standard one like Mvvm Toolkit or ReactiveUI? Do you have DataTemplates for each VM type? Are you using WPF? Avalonia? Something else? What does your View look like?
kianyuen
kianyuen2mo ago
Sorry, I hit the msg limit so I didn't provide more info. I am using WPF, I'm not using a MVVM framework. This is the ViewModelBase
public abstract class ViewModelBase
{
public event PropertyChangedEventHandler PropertyChanged;

public void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public abstract class ViewModelBase
{
public event PropertyChangedEventHandler PropertyChanged;

public void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
This is the MainView.xaml
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Styles/ButtonStyles.xaml"/>
<ResourceDictionary Source="/Styles/IconsDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
<DataTemplate DataType="{x:Type viewModel:BloodPressureViewModel}">
<local:BloodPressureView/>
</DataTemplate>
<DataTemplate DataType="{x:Type viewModel:HeightWeightViewModel}">
<local:HeightWeightView/>
</DataTemplate>
<DataTemplate DataType="{x:Type viewModel:BMIViewModel}">
<local:BMIView/>
</DataTemplate>
</ResourceDictionary>

</Window.Resources>
<Window.DataContext>
<viewModel:MainViewModel/>
</Window.DataContext>
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Styles/ButtonStyles.xaml"/>
<ResourceDictionary Source="/Styles/IconsDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
<DataTemplate DataType="{x:Type viewModel:BloodPressureViewModel}">
<local:BloodPressureView/>
</DataTemplate>
<DataTemplate DataType="{x:Type viewModel:HeightWeightViewModel}">
<local:HeightWeightView/>
</DataTemplate>
<DataTemplate DataType="{x:Type viewModel:BMIViewModel}">
<local:BMIView/>
</DataTemplate>
</ResourceDictionary>

</Window.Resources>
<Window.DataContext>
<viewModel:MainViewModel/>
</Window.DataContext>
My view consists of a ContentPresenter, some RadioButton, and a Title textblock. The binding seems to call the command normally, and the debug stop for the ExecuteShow...Command does trigger when the corresponding Radio button is pressed. No update on the UI tho.
Klarth
Klarth2mo ago
Looks ok to me. How are you showing CurrentChildView and Title ? I'd still recommend using Mvvm Toolkit. Wait, not ok. public abstract class ViewModelBase This needs to implement INotifyPropertyChanged Mvvm Toolkit ships with very good implementations of INotifyPropertyChanged and ICommand. Your implementation is quite poor, although it should work once you actually implement the interface.
kianyuen
kianyuen2mo ago
Ah thanks, I wanted to use a framework but I'm still learning about MVVM (also more tutorial not using a fw).
Klarth
Klarth2mo ago
Most modern tutorials are using Mvvm Toolkit, AFAIK. Even the one I'm in the middle of writing is doing it. I cover how to DIY those types, show how they're used, and then immediately move to Mvvm Toolkit while stating to never use those old types after showing the differences. :kekw:
kianyuen
kianyuen2mo ago
Too bad WPF isn't modern, I'm a bit in the dark about C# in general too, lol. Process of less boilerplate, better life
Klarth
Klarth2mo ago
You could check SingletonSean on YouTube for more modern WPF stuff. Most of the improvements have been community-driven. Knowing how and when to use certain features, plus a lot of work on open source themes.
Want results from more Discord servers?
Add your server