Many people asked me how to enable/disable button depending on a few TextBoxes. I would strongly recommend Caliburn but I know not everyone can use it. So I’ve decided to post a very simple solution to that problem.
First of all we need a ViewModel and I will use a very simple class which has IsValid method – checking if data is valid, ICommand property to be bound to a Button and an action to be executed when the button is pressed.
class PersonViewModel
{
public string Name { get; set; }
public int Age { get; set; }
public bool IsValid()
{
if(string.IsNullOrEmpty(this.Name))
{
return false;
}
if(this.Age < 5 || this.Age > 120)
{
return false;
}
return true;
}
public ICommand OkCommand
{
get { return new DelegatedCommand(this.OkAction, this.IsValid); }
}
private void OkAction()
{
MessageBox.Show("ok!");
}
}
TextBox.Text properties can now be bound to properties of this class and button’s command can be bound to OkCommand. Automatically button will be enable when command can be executed and disabled when command cannot be executed:
<TextBox Text="{Binding Path=Name}"/>
<TextBox Text="{Binding Path=Age}"/>
<Button Command="{Binding Path=OkCommand}" Content="ok"/>
My ICommand implementation in this example is very naive. Maybe a better one in a next post? :-)
Results disabled and enabled:
Code here
Monika
Did you know that content of a ToolTip is neither a part of visual nor logical tree? I didn't so I was trying to bind a ToolTip.Content using ElementName. And it didn't work:
<TextBlock Name="box" Text="Text to place inside tooltip" />
<Button Content="Can't Bind">
<Button.ToolTip>
<ToolTip Content="{Binding ElementName=box,
Path=Text}"/>
</Button.ToolTip>
</Button>
Button has a tiny empty tooltip:
This code seemed perfectly fine for me so it took me a lot of time to google the answer. The only way to make that binding happen doesn't look nice but it's a simple trick: bind to a Grid DataContext. Seriously :-)
<Grid DataContext="{Binding ElementName=box, Path=Text}" >
<Button Content="Tricky Evil Solution ;-)"/>
<Grid.ToolTip>
<ToolTip Content="{Binding Path=PlacementTarget.DataContext,
RelativeSource={RelativeSource Self}}"/>
</Grid.ToolTip>
</Grid>
And now the tooltip looks ok:
My original problem was binding a ToolTip.Content to validation errors and I really needed a way to do that. Please tell me if you know a better one :-)
Code can be found here.
Monika
Update: This works too! :-)
<Button ToolTip="{Binding ElementName=box, Path=Text}" />