- C# WPF Introduction
- C# WPF First Program
- C# WPF without XAML – Window Class
- C# WPF First Window Introduction
- C# WPF Create a Simple Binding Object in Code Behind
- C# WPF Data Binding
- C# WPF Data Binding and Triggers
- C# WPF Data Binding and Binding Direction
- C# WPF Data Binding and Triggers MouseOvers
- C# WPF Value Converters
- C# WPF ComboBox Control
- C# WPF Bindings and ItemsControls
- C# WPF Styles
- C# WPF RGB Colour Viewer
- C# WPF XAML Background Colour
- C# WPF Events
- C# WPF Dynamic Binding to External Objects
- C# WPF Multiple Bindings on an Object
This post is a continuation of the previous post on data binding.
From the previous post, when you change the position of the slider, the value in the TextBox is updated immediately. But when you change the value of the TextBox, the slider isn’t updated until the focus in the window changes. The differences in their behavior depend on two factors—the direction of the update and the value of the Binding object’s UpdateSourceTrigger. When you change the text box to 4, as shown below, and press Enter, the slider does not update by slider over to 4. If you press the Tab key the focus of the text box is lost and the slider updates. So, there are differences in their behaviour. The differences in their behavior depend on two factors — the direction of the update and the value of the Binding object’s UpdateSourceTrigger.
UpdateSourceTrigger
When the direction of the update is from the source to the target, the update always happens immediately. When the direction of the update is from the target to the source, then when the update occurs depends on the value of the UpdateSourceTrigger property of the Binding. Target to source is text box to slider, in this example. In the XAML shown below, the UpdateSourceTrigger is set to PropertyChanged. Now, the slider does not wait for the text box to lose its focus. The slider is updated immediately.
<Window x:Class="BindSlider2.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:BindSlider2" mc:Ignorable="d" Title="MainWindow" Height="150" Width="360"> <StackPanel> <TextBox Margin="10" Name="tbName" Text="{Binding ElementName=sldrSlider, Path=Value, UpdateSourceTrigger=PropertyChanged}"/> <Slider Name="sldrSlider" TickPlacement="TopLeft" Margin="10" Maximum="10"/> <Label x:Name="label" Content="Book: Illustrated WPF by Daniel M. Solis, Ch 8 page 196" HorizontalAlignment="Left" Height="26" Margin="10,0,0,0" Width="323"/> </StackPanel> </Window>
Explicit
Another option is illustrated by the window shown below. In this case, the source (slider) is updated only when the Trigger button is clicked.
<Window x:Class="DataBinding3.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:DataBinding3" mc:Ignorable="d" Title="MainWindow" Height="180" Width="360"> <StackPanel> <TextBox Margin="10" Name="tbValue" Text="{Binding ElementName=sldrSlider, Path=Value, UpdateSourceTrigger=Explicit}"/> <Slider Name="sldrSlider" TickPlacement="TopLeft" Margin="10" Maximum="10"/> <Button Click="Button_Click">Trigger</Button> <Label x:Name="label" Content="Book: Illustrated WPF by Daniel M. Solis, Ch 8 page 196" HorizontalAlignment="Left" Height="26" Margin="10,0,0,0" Width="323"/> </StackPanel> </Window>
Below is the code you need to write
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace DataBinding3 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void Button_Click(object sender, RoutedEventArgs e) { // Update the slider (source) with the value in the text box (target) // only when the Trigger button is clicked (not immedately // and not on loss of focus of text box). To do this // get the BindingExpression for the target property // and call its UpdateSource method. BindingExpression be = tbValue.GetBindingExpression(TextBox.TextProperty); be.UpdateSource(); } } }
In the code-behind, you need to create an event handler for the button, to trigger the explicit update. You accomplish this by getting the BindingExpression for the target property and calling its UpdateSource method