I got a issue with my code, I'm trying to execute a command on a button but nothing is happening.
I'm guessing it's because my viewmodel is static but maybe you guys can help me how to make it work.
This is a snip of the XAML, I removed all the non essential code.
<UserControl x:Class="Dossier_Registratie.Views.OverledeneView"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Dossier_Registratie.ViewModels"
mc:Ignorable = "d"
d:DesignHeight="696.96" d:DesignWidth="1190.257"
DataContext="{x:Static local:OverledeneViewModel.Instance}">
<Button x:Name="lbl_SaveOverledene" Command="{Binding Path=SaveCommand}" Content="Volgende" Margin="1035,16,15,0" VerticalAlignment="Top" Height="31" Width="138.257" TabIndex="29" FontFamily="Arial" />
This is part of the viewmodel
public class OverledeneViewModel : ViewModelBase
{
//->Commands
public ICommand SaveCommand { get; }
//Builder
private OverledeneViewModel()
{
overledeneRepository = new OverledeneRepository();
UitvaartLeider = new OverledeneUitvaartleiderModel();
PersoonsGegevens = new OverledenePersoonsGegevensModel();
OverlijdenInfo = new OverledeneOverlijdenInfoModel();
SaveCommand = new ViewModelCommand(ExecuteSaveCommand, CanExecuteSaveCommand);
}
public static OverledeneViewModel Instance { get; } = new();
private bool CanExecuteSaveCommand(object obj)
{
bool validData;
if(string.IsNullOrWhiteSpace(AchternaamOverledene)
|| string.IsNullOrWhiteSpace(VoornaamOverledene)
|| string.IsNullOrWhiteSpace(GeboortedatumOverledene))
{
validData = false;
}
else
{
validData = true;
}
return validData;
}
private void ExecuteSaveCommand(object obj)
{
var AddUitvaartleider = overledeneRepository.AddUitvaartleider;
var AddPersoonsGegevens = overledeneRepository.AddPersoonsGegevens;
var AddOverlijdenInfo = overledeneRepository.AddOverlijdenInfo;
if (AddUitvaartleider.ToString() != "InsertUitvaartleiderSucces")
throw new Exception("Uitvaarleider insert has failed");
if (AddPersoonsGegevens.ToString() != "InsertPersoonsGegevensSucces")
throw new Exception("Persoonsgegevens insert has failed");
if (AddOverlijdenInfo.ToString() != "InsertOverlijdenInfoSucces")
throw new Exception("OverlijdenInfo insert has failed");
}
}
ViewModelCommand
public class ViewModelCommand : ICommand
{
//fields
private readonly Action<object> _executeAction;
private readonly Predicate<object> _canExecuteAction;
//Constructor
public ViewModelCommand(Action<object> executeAction)
{
_executeAction = executeAction;
_canExecuteAction = null;
}
public ViewModelCommand(Action<object> executeAction, Predicate<object> canExecuteAction)
{
_executeAction = executeAction;
_canExecuteAction = canExecuteAction;
}
//Events
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value;}
}
//Methods
public bool CanExecute(object parameter)
{
return _canExecuteAction == null ? true : _canExecuteAction(parameter);
}
public void Execute(object parameter)
{
_executeAction(parameter);
}
}
I'm missing something here but I can find what, If I put a messagebox inside the canexecute it show directly when openening the application but not when i'm clicking the button.
Any help would be greatly appreciated.
Kind regards, Patrick
You return a new Command instance anytime someone calls your property SaveCommand
. You just need to create the command instance once. So a
change from
//->Commands
public ICommand SaveCommand { get { return new ViewModelCommand(ExecuteSaveCommand, CanExecuteSaveCommand); }}
//Builder
private OverledeneViewModel()
{
overledeneRepository = new OverledeneRepository();
UitvaartLeider = new OverledeneUitvaartleiderModel();
PersoonsGegevens = new OverledenePersoonsGegevensModel();
OverlijdenInfo = new OverledeneOverlijdenInfoModel();
}
to
// ->Commands
public ICommand SaveCommand { get; }
//Builder
private OverledeneViewModel()
{
overledeneRepository = new OverledeneRepository();
UitvaartLeider = new OverledeneUitvaartleiderModel();
PersoonsGegevens = new OverledenePersoonsGegevensModel();
OverlijdenInfo = new OverledeneOverlijdenInfoModel();
SaveCommand = new ViewModelCommand(ExecuteSaveCommand, CanExecuteSaveCommand); }
}
will maybe/likely fix it.
Also you need to raise the ICommand.CanExecuteChanged
event
anytime one of the properties evaluated in the CanExecute callback (which are AchternaamOverledene
, VoornaamOverledene
, GeboortedatumOverledene
) changes. Else the command may rest disabled if CanExecuteSaveCommand
returned false in its first invocation.