Jessica Boxer
Jessica Boxer

Reputation: 543

Binding to an expression

I have an onscreen numeric keypad to type a PIN. What I want to do is disable the buttons when four digits of PIN are entered. I can certainly do this with code pretty easily, but it seems to me to be the sort of thing that should be done with binding.

Something like:

<Button Style="Whatever" IsEnabled="{Binding ElementName=PinBox ???}"/>

It seems there isn't a way to do that (which to be honest seems rather primitive to me.) So I considered the alternative, which is a plain property on the underlying Window class. But I'm not sure how to bind to it. Do I need to specify the class itself as its own data context, or do I need to extract the PIN string into a View Model?

And subsequently, how do I get the plain property to update the GUI?

I suppose I could defined a view model class and have a dependency property called "ButtonsEnabled" but it seems kind of heavyweight for such a simple problem.

Let me know if I am missing something.

Upvotes: 15

Views: 18595

Answers (4)

Avani Vadera
Avani Vadera

Reputation: 526

You can write a converter which return boolean depending on digits in TextBox

The XAML fo r button would be

<Button Content="Test" IsEnabled="{Binding ElementName=PinBox,Path=Text,Converter={StaticResource DigitsToBoolConverter}}" Grid.Row="1" Height="20" Width="100"></Button>

where PinBox is the textbox name used to enter pin.

The Converter function is

 public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
 {
     return value.ToString().Length >= 4;
 }

Upvotes: 16

Stafford Williams
Stafford Williams

Reputation: 9806

Another way using commands:

XAML:

<Button Content="2" Style="Whatever" Command={Binding MyCommand} CommandParamater="2"/>

ViewModel:

public ICommand MyCommand { get; private set; }
public string PinNumber { get; private set; }
public void Init()
{
  MyCommand = new RelayCommand(
    param => AddPinNumberDigit(param),
    param => CanAddPin);
}
private void AddPinNumberDigit(string digit)
{
  PinNumber += digit;
}
public bool CanAddPin { 
  get
  {
    return PinNumber.Length < 3;
  }
}

Upvotes: 9

Stafford Williams
Stafford Williams

Reputation: 9806

Create a converter that will return true or false based on PinBox.Text.Length.

Your xaml would then become:

<Button Style="Whatever" IsEnabled={Binding ElementName=PinBox, Converter={StaticResource yourConverter}}/>

Upvotes: 0

Tyson
Tyson

Reputation: 14734

Nope, your not missing anything, WPF out of the box bindings do not support expressions.

There has been some people implementing their own classes that add this type of functionality: http://www.11011.net/wpf-binding-expressions

But really, this is what the ViewModel pattern is for. Use it, it's not heavyweight.

Upvotes: 4

Related Questions