"Updatesourcetrigger=Propertychanged" Equivalent for a Windows Phone 7 Textbox

UpdateSourceTrigger=PropertyChanged equivalent for a Windows Phone 7 TextBox

Silverlight for WP7 does not support the syntax you've listed. Do the following instead:

<TextBox TextChanged="OnTextBoxTextChanged"
Text="{Binding MyText, Mode=TwoWay,
UpdateSourceTrigger=Explicit}" />

UpdateSourceTrigger = Explicit is a smart bonus here. What is it? Explicit: Updates the binding source only when you call the UpdateSource method. It saves you one extra binding set when the user leaves the TextBox.

In C#:

private void OnTextBoxTextChanged( object sender, TextChangedEventArgs e )
{
TextBox textBox = sender as TextBox;
// Update the binding source
BindingExpression bindingExpr = textBox.GetBindingExpression( TextBox.TextProperty );
bindingExpr.UpdateSource();
}

“UpdateSourceTrigger=PropertyChanged” equivalent for a TextBox in WinRT-XAML

It seems there is no GetBindingExpression or equivalent workaround. However you can extend the TextBox like this: https://mytoolkit.svn.codeplex.com/svn/WinRT/Controls/ExtendedTextBox.cs

Still this doesn't solve the problem itself... (it's really sad)

See also:

  • http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/a04dc907-9ca8-4302-bbad-c00b01b8193f/
  • http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/69214cce-787b-40c6-9d40-a556c5636119/
  • http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/775f1692-2837-471c-95fc-710bf0e9cc53

Cursor Goes Back To Start Why?

The problem is that "." by itself is not a valid decimal so when the binding try to update Price it fail. Latter when you enter ".5" it consider it a valid number and update the value of Price but when price raise property changed and it is converted back to Text it is converted to 0.5 which force a "programmatic" update of the text box and will reset the cursor to the first position.

To fix this problem the best solution I see is probably use a string property to back up the Price and update the decimal value "manually":

private decimal price = 0.00M;

/// <summary>
/// Sets and gets the Price property.
/// Changes to that property's value raise the PropertyChanged event.
/// </summary>
public decimal Price
{
get
{
return price;
}

set
{
if (price == value)
{
return;
}

RaisePropertyChanging(() => Price);
price = value;
RaisePropertyChanged(() => Price);

this.PriceStr = this.Price.ToString();

}
}

private string priceStr=0.00M.ToString();
/// <summary>
/// Sets and gets the Price property.
/// Changes to that property's value raise the PropertyChanged event.
/// </summary>
public string PriceStr
{
get
{
return priceStr;
}

set
{
if (priceStr == value)
{
return;
}

priceStr = value;

isPriceAValidStr=decimal.TryParse(this.PriceStr, out price);

RaisePropertyChanged(() => Price);
RaisePropertyChanged(() => PriceStr);
}
}

private bool isPriceAValidStr = true;

and change you binding of Text to PriceStr.

Also there is another problem, even with InputScope="Number" there is still some way to enter text in your text box:

  • by using the harware keyboard for phone which have one (in the emulator you can simulate that by pressing the page down key and then you will be able to use your keyboard to enter text). To fix that you can register for the key_down event and do some condition check on e.Key and reject all key that you don't want by setting e.Handled = true;. Also you can use this to also prevent user to enter two time a .
  • by copying some text from another text box were text is enabled (probably should just also removed all invalid letters in TextChanged)

Why data binding is not working with PropertyChanged?

UpdateSourceTrigger=PropertyChanged is not supported in Windows Phone XAML.

You can use UpdateSourceTrigger=Explicit instead,
and handle the source updating in the code behind:

private void OnTextBoxTextChanged( object sender, TextChangedEventArgs e )
{
TextBox textBox = sender as TextBox;
BindingExpression bindingExpr = textBox.GetBindingExpression( TextBox.TextProperty );
bindingExpr.UpdateSource();
}

Another alternative would be to use Coding4Fun's library BindingHelper. in that case, the syntax would be:

<TextBox   
Text="{Binding FooBar, Mode=TwoWay}"
local:TextBinding.UpdateSourceOnChange="True" />

Windows Phone TextBox raise command RaiseCanExecuteChanged on TextChanged?

Try to play with UpdateSourceTrigger property of binding. TextBox has it set to LostFocus event by default, hence RaiseCanExecuteChanged was called after that event in this case. In WPF, we can set it to PropertyChanged. With that setting RaiseCanExecuteChanged will be raised immediately after text property value changed, without waiting for LostFocus event :

<TextBox Text="{Binding UserName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

Unfortunately, PropertyChanged isn't available in silverlight for windows phone. We need to use Explicit and raise binding UpdateSource event manually upon TextChanged event raised :

<TextBox Text="{Binding UserName, Mode=TwoWay, UpdateSourceTrigger=Explicit}" 
TextChanged="OnTextChanged"/>

//in code-behind
private void OnTextChanged(object sender, TextChangedEventArgs e)
{
TextBox textBox = sender as TextBox;
BindingExpression bindingExpr = textBox.GetBindingExpression(TextBox.TextProperty);
//Manually call UpdateSource
bindingExpr.UpdateSource();
}

Note that code-behind in this case is fine (from MVVM pont-of-view), because it is just doing some UI/binding related tasks, not data related tasks.

References :

  • "UpdateSourceTrigger=PropertyChanged" equivalent for a Windows Phone 7 TextBox
  • Binding.UpdateSourceTrigger Property

Two-way Binding error in longlistselector, with own datatemplate and class

If you want your TextBox to be two way binded, then you should use Text="{Binding Path=Post,Mode=TwoWay}"

Windows phone don't support UpdateSourceTrigger=PropertyChanged but you can find a way to do that here .

Or an alternative is to use the UpdateTextBindingOnPropertyChanged from the Prism library. You can just download the source code of the file I linked and set it in in xaml like this:

<TextBox ...>
<i:Interaction.Behaviors>
<prism:UpdateTextBindingOnPropertyChanged/>
</i:Interaction.Behaviors>
</TextBox>

ImageSource in XAML binding issue Windows phone

Your property name is PlayerImage not PlayerImageUri change it in PropertyChanged call

this.PropertyChanged(this, new PropertyChangedEventArgs("PlayerImageUri"));

should be

this.PropertyChanged(this, new PropertyChangedEventArgs("PlayerImage"));


Related Topics



Leave a reply



Submit