I have a WPF application and I want the Start button control only enabled if they have to have specified a value in the text box for 'Download Path'.
My ViewModel contains a property for my model "ConfigurationSettings" and an ICommand implementation (CommandImp) for the button:
public class MainWindowViewModel : BaseNotifyPropertyChanged
{
private ConfigurationSettings _configurationSettings { get; set; }
public ConfigurationSettings ConfigurationSettings
{
get
{
return _configurationSettings;
}
set
{
if (_configurationSettings != value)
{
_configurationSettings = value;
RaisePropertyChanged("ConfigurationSettings");
}
}
}
public CommandImp StartCommand { get; set; } // this is an implementation of ICommand
public MainWindowViewModel()
{
StartCommand = new CommandImp(OnStart, CanStart);
_configurationSettings = new ConfigurationSettings();
_configurationSettings.PropertyChanged += delegate (object o,
PropertyChangedEventArgs args)
{
StartCommand.RaiseCanExecuteChanged(); // break point here is never reached
};
}
private bool CanStart()
{
if (!String.IsNullOrEmpty(ConfigurationSettings.DownloadPath))
{
return true;
}
return false;
}
}
In my XAML I have a Start button and the with Command = "{Binding StartCommand}".
My ConfigurationSettings class just has a string for the DownloadPath which is bound to a textbox in the XAML:
public class ConfigurationSettings : BaseNotifyPropertyChanged
{
private string _downloadPath { get; set; }
public string DownloadPath
{
get { return _downloadPath; }
set
{
if (_downloadPath != value)
{
_downloadPath = value;
RaisePropertyChanged("DownloadPath"); // break point here IS reached
}
}
}
}
When the user enters a DownloadPath, I expect it to be triggering the PropertyChanged Event, and running my delegate method defined in the ViewModel constructor.
If I move the Command Button inside the ConfigurationSettings class I can do away with event subscription and just use StartCommand.RaiseCanExecuteChanged() right beneath RaisePropertyChanged("DownloadPath");. But I don't want the ICommand as part of my Model.
How can I trigger CanStart() when one of the properties of ConfigurationSettings changes?
UPDATE: Here is the XAML for the text box binding:
<TextBlock Text="{Binding ConfigurationSettings.DownloadPath, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" TextWrapping="WrapWithOverflow" />
And the button:
<Button Content="Start" Command="{Binding StartCommand}"></Button>
I should note that the bindings are working correctly. When I update the textblock, I can see in the ViewModel that ConfigurationSettings.DownloadPath is correctly being updated.
BaseNotifyPropertyChanged is an implementation of INotifyPropertyChanged like so:
public class BaseNotifyPropertyChanged : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string property)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}
}
I don't seem to be having any issues with the property changed event. I can put a break point in here and it is hit when I update the DownloadPath text box. It's when I subscribe to this PropertyChanged event in my ViewModel constructor, my delegate method isn't firing.
DataContext
for the control in your code or in xaml? Perhaps you have them set in xaml only and theDataContext
is not the instance from your MainVM? Hope this makes sense. – XAMlMAXnew MainViewModel();
. Have you tried creating view model manually and then test if theCanStart()
works? – XAMlMAX