Enable button based on TextBox value (WPF)
Posted
by zendar
on Stack Overflow
See other posts from Stack Overflow
or by zendar
Published on 2010-03-11T18:53:20Z
Indexed on
2010/03/12
12:27 UTC
Read the original article
Hit count: 709
This is MVVM application. There is a window and related view model class.
There is TextBox
, Button
and ListBox
on form. Button is bound to DelegateCommand
that has CanExecute
function. Idea is that user enters some data in text box, presses button and data is appended to list box.
I would like to enable command (and button) when user enters correct data in TextBox
. Things work like this now:
CanExecute()
method contains code that checks if data in property bound to text box is correct.- Text box is bound to property in view model
UpdateSourceTrigger
is set toPropertyChanged
and property in view model is updated after each key user presses.
Problem is that CanExecute()
does not fire when user enters data in text box. It doesn't fire even when text box lose focus.
How could I make this work?
Edit:
Re Yanko's comment:
Delegate command is implemented in MVVM toolkit template and when you create new MVVM project, there is Delegate command in solution. As much as I saw in Prism videos this should be the same class (or at least very similar).
Here is XAML snippet:
...
<UserControl.Resources>
<views:CommandReference x:Key="AddObjectCommandReference"
Command="{Binding AddObjectCommand}" />
</UserControl.Resources>
...
<TextBox Text="{Binding ObjectName, UpdateSourceTrigger=PropertyChanged}"> </TextBox>
<Button Command="{StaticResource AddObjectCommandReference}">Add</Button>
...
View model:
// Property bound to textbox
public string ObjectName
{
get { return objectName; }
set {
objectName = value;
OnPropertyChanged("ObjectName");
}
}
// Command bound to button
public ICommand AddObjectCommand
{
get
{
if (addObjectCommand == null)
{
addObjectCommand = new DelegateCommand(AddObject, CanAddObject);
}
return addObjectCommand;
}
}
private void AddObject()
{
if (ObjectName == null || ObjectName.Length == 0)
return;
objectNames.AddSourceFile(ObjectName);
OnPropertyChanged("ObjectNames"); // refresh listbox
}
private bool CanAddObject()
{
return ObjectName != null && ObjectName.Length > 0;
}
As I wrote in the first part of question, following things work:
- property setter for
ObjectName
is triggered on every keypress in textbox - if I put
return true;
inCanAddObject()
, command is active (button to)
It looks to me that binding is correct.
Thing that I don't know is how to make CanExecute()
fire in setter of ObjectName
property from above code.
Re Ben's and Abe's answers:
CanExecuteChanged()
is event handler and compiler complains:The event 'System.Windows.Input.ICommand.CanExecuteChanged' can only appear on the left hand side of += or -=
there are only two more members of
ICommand
:Execute()
andCanExecute()
Do you have some example that shows how can I make command call CanExecute()
.
I found command manager helper class in DelegateCommand.cs
and I'll look into it, maybe there is some mechanism that could help.
Anyway, idea that in order to activate command based on user input, one needs to "nudge" command object in property setter code looks clumsy. It will introduce dependencies and one of big points of MVVM is reducing them.
Is it possible to solve this problem by using dependency properties?
© Stack Overflow or respective owner