Seeing that the TextBox in focus doesn’t update the bound object? The reason might be that the focus is not lost. The issue can be related to an AppBarButton. This button doesn’t take the focus on click – and binding to the source happens on losing the focus.
The issues and how this can be solved is described here – with a Universal Windows Platform (UWP) application.
XAML Compiled Binding
The sample code is available at More Samples.
Let’s get into a sample. The sample application defines simple properties One
, Two
, and Three
which will be entered in the UI, and shown with the UWP MessageDialog
in the method ShowValues
.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public string One { get; set; } | |
public string Two { get; set; } | |
public string Three { get; set; } | |
public async void ShowValues() | |
{ | |
await new MessageDialog($"One: {One}, Two: {Two}, Three: {Three}").ShowAsync(); | |
} |
In the XAML file, the first TextBox
is bound to the property One
with a simple two-way binding. The second TextBox
configures the UpdateSourceTrigger
to PropertyChanged
. This way, binding from the UI to the source code happens with every property change. The default value for the UpdateSourceTrigger
is LostFocus
. The third TextBox
control has the same binding as the first one.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<TextBox Header="One" Text="{x:Bind One, Mode=TwoWay}" /> | |
<TextBox Header="Two" Text="{x:Bind Two, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> | |
<TextBox Header="Three" Text="{x:Bind Three, Mode=TwoWay}" /> |
The sample code makes use of compiled binding. Similar, you can use the traditional binding based on reflection. The issues are the same.
Showing the updated values
The actual values from the code are shown on invoking the ShowValues
method. This method is invoked via the Click
event of AppBarButton
and Button
controls. The first AppBarButton
just resets the properties. The second AppBarButton
defines a handler for the Click
event to show the values, and a Button
control that follows defines the Click
event similar.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<AppBarButton Icon="Refresh" Click="{x:Bind Refresh, Mode=OneTime}" /> | |
<AppBarButton Icon="Emoji" Click="{x:Bind ShowValues, Mode=OneTime}" /> | |
<Button Content="Show" Click="{x:Bind ShowValues, Mode=OneTime}" /> | |
<AppBarButton Icon="Emoji2" AllowFocusOnInteraction="True" Click="{x:Bind ShowValues, Mode=OneTime}" /> |
Running the application and enter values in the three TextBox
controls, and clicking on the AppBarButton
, the first two values are shown, but the last one not. The first TextBox
control has lost the focus while selecting the second one. With the second TextBox
, the source is updated with every property change – because of the change with UpdateSourceTrigger
. If you keep the focus in this textbox, the current values are shown. Clicking on the AppBarButton
while the third TextBox
has the focus, source updates do not occur.
This behavior is different clicking on the Button
control. The Button
control gets the focus, thus updates on losing the focus do occur.
Taking the Focus with the AppBarButton
What’s the reason for the AppBarButton
not taking the focus? With some scenarios you don’t want the focus to be taken away from the TextBox
. For example, the user wants to mark some text bold or italics by clicking on a button. Here, the focus should stay in the TextBox
control.
In the scenario where the user enters multiple values, the focus should be lost. To solve the issue, one way is to use the Button
control instead of the AppBarButton
. You can use SymbolIcon
or FontIcon
as content for the Button
to get a similar look. Another way is to use the PropertyChanged
value with the UpdateSourceTrigger
property. However, this creates too much runtime activity with every property change – and you might get in issues with a custom converter receiving interim values.
The best way is to just take the focus clicking the AppBarButton
. You just need to set the property AllowFocusOnInteraction
with this control. Setting the value to True
, the AppBarButton
control now behaves like the Button
control in this scenario and takes the focus.
The
AllowFocusOnInteraction
property has been introduced in the Windows 10 Anniversary Edition (build 14393, API contract v3).
Be aware, that using the AppBarButton
in a CommandBar
, setting the AllowFocusOnInteraction
property on the AppBarButton
is not enough. You need to set this property on the CommandBar
as well.
Summary
There are cases where you see unexpected results like no source updates happening. There are reasons behind it – such as the AppBarButton
not taking the focus. This issue can be solved easily by setting the AllowFocusOnInteraction
property.
If this information helped you fix an issue, consider buying me a coffee which helps me staying up longer and writing more articles.
More information on XAML and writing UWP applications is in my book Professional C# 7 and .NET Core 2.0, and in my Programming Windows Apps workshops.
Enjoy learning and programming!
Christian
One thought on “Binding to Source Updates not happening with TextBox and AppBarButton”