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 theUpdateSource
method. It saves you one extra binding set when the user leaves theTextBox
.
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 settinge.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
Matching Strings with Wildcard
Loading Multiple Versions of the Same Assembly
Is There a Generic Constraint I Could Use for the + Operator
What Is the Correct Performance Counter to Get CPU and Memory Usage of a Process
Setting Up Hook on Windows Messages
Detect Active Window Changed Using C# Without Polling
Why We Need Thread.Memorybarrier()
How to Post Data Using Httpclient
How to Protect Resources That May Be Used in a Multi-Threaded or Async Environment
Is Inaccessible Due to Its Protection Level
Differencebetween Int, Int16, Int32 and Int64
Determine If Uploaded File Is Image (Any Format) on MVC