Just started working with the MVVM design pattern and I'm stuck.
When my application launches, I have a treeview populated with a list of objects names. I've setup the IsChecked Binding, and it works fine. I'm trying to setup the IsEnabled Binding.
I want the user to select the items in the treeview he wants, then click one of three buttons to perform an action. On click, I want the selected items to remain in the treeview, but be disabled, so the user cannot perform another action on those items.
I'm using a RelayCommand class in the application.
private ICommandOnExecute _execute;
private ICommandOnCanExecute _canExecute;
public RelayCommand(ICommandOnExecute onExecuteMethod,
ICommandOnCanExecute onCanExecuteMethod)
{
_execute = onExecuteMethod;
_canExecute = onCanExecuteMethod;
}
#region ICommand Members
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public bool CanExecute(object parameter)
{
return _canExecute.Invoke(parameter);
}
public void Execute(object parameter)
{
_execute.Invoke(parameter);
}
#endregion
My object model class uses this
private bool _isEnabled;
public bool IsEnabled
{
get { return true; }
set { _isEnabled = value};
}
Then within my button method I have
if (interfaceModel.IsChecked)
{
//Does Something
MyObjectName.IsEnabled = false;
}
And here is my xaml
<CheckBox IsChecked="{Binding IsChecked}" IsEnabled="{Binding IsEnabled, Mode=TwoWay}">
<TextBlock Text="{Binding MyObjectName}" Margin="5,2,1,2" HorizontalAlignment="Left" />
</CheckBox>
You need a setup like this:
// Your ViewModel should implement INotifyPropertyChanged
class ViewModel : INotifyPropertyChnaged
{
private bool _isEnabled;
public bool IsEnabled
{
get { return _isEnabled; }
set
{
_isEnabled = value;
SetPropertyChanged("IsEnabled"); // Add this to your setter.
}
}
// This comes from INotifyPropertyChanged - the UI will listen to this event.
public event PropertyChangedEventHandler PropertyChanged;
private void SetPropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged( this, new PropertyChangedEventArgs(property) );
}
}
}
Note that PropertyChanged comes from having your ViewModel implement INotifyPropertyChanged. To notify the UI, you have to raise that event, and tell it what property was changed (usually in the setter - see above).
Alternatively, if you don't like raw strings (I don't, personally), you can use generics and expression trees to do something like this:
public void SetPropertyChanged<T>(Expression<Func<T, Object>> onProperty)
{
if (PropertyChanged != null && onProperty.Body is MemberExpression)
{
String propertyNameAsString = ((MemberExpression)onProperty.Body).Member.Name;
PropertyChanged(this, new PropertyChangedEventArgs(propertyNameAsString));
}
}
Where in your setter you can say:
public bool IsEnabled
{
set
{
_isEnabled = value;
SetPropertyChanged<ViewModel>(x => x.IsEnabled);
}
}
And now it's strongly typed, which is kinda nice.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With