programming4us
programming4us
DATABASE

Silverlight : Data Binding - Controlling Updates

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019

1. Problem

You would like to have explicit programmatic control on when property updates happen in a TwoWay data binding scenario.

2. Solution

Set the UpdateSourceTrigger attribute to Explicit in the binding declaration and programmatically invoke BindingExpression.UpdateSource().

3. How It Works

The default behavior of most Silverlight controls is to send the updates occurring as a result of user edits directly to the bound property as soon as they occur. For instance, when you change the text in a TextBox, whose Text property is data bound in a TwoWay mode, the bound property is updated as soon as the user tabs out or focus is shifted somewhere else through some other means.

Often, it may be desirable to hold the updates and batch them at the end of an edit session through some explicit user-driven mechanism like a Save button. A multitude of reasons could drive a decision like that: computed fields that can only be calculated when multiple other fields are populated, validation logic that involves dependencies across multiple fields, some preprocessing of the edited data before updates are applied, and so on.

Silverlight offers you this control through the Binding.UpdateSourceTrigger property. Setting this property to UpdateSourceTrigger.Explicit causes the runtime to hold all property updates in the anticipation that you will perform the updates explicitly in code. The following code snippet shows a binding declaration for the Text property on a TextBox with the UpdateSourceTrigger attribute set to Explicit:

<TextBox HorizontalAlignment="Stretch"
 Margin="1,1,1,1"
 x:Name="tbxLName"
 VerticalAlignment="Stretch"
 Text=
"{Binding LastName, Mode=TwoWay,UpdateSourceTrigger=Explicit}"
 Grid.Row="1"
 Grid.Column="3"
 Width="Auto"
 Grid.RowSpan="1"
 Grid.ColumnSpan="3" />

To actually perform the updates, you need to access the BindingExpression instance supporting the binding in question and invoke the BindingExpression.UpdateSource() method on it. You can acquire the BindingExpression instance in question by using the FrameworkElement.GetBindingExpression() method and passing in the property whose related BindingExpression you may need. This code snippet shows an example:

BindingExpression beLastName = tbxLName.GetBindingExpression(TextBox.TextProperty);
beLastName.UpdateSource();

					  

Note that any validation logic that you have built into the property setters will execute only when UpdateSource() is invoked for that specific binding. So if you are batching the calls to UpdateSource(), it will cause all validation logic to be batched as well.

4. The Code

Figure 1 shows the state of the edit user interface before and after the Save button is clicked. Note that while you have potentially incorrect data in the state, zipcode and phone number fields, the validation check results only show up once the updates are attempted.

Figure 1. Employee edit user interface before and after batched update attempt

Listing 1 shows the XAML for the main page.

Listing 1. XAML for MainPage
<UserControl x:Class="Recipe4_7.MainPage"
             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:local="clr-namespace:Recipe4_7"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:input="clr-
namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.Input"
             Width="400"
             Height="450">
    <UserControl.Resources>

    <local:BoolToVisibilityConverter x:Key="REF_BoolToVisibilityConverter" />

    <DataTemplate x:Key="dtEmployee">
      <Grid>
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="Auto" />
          <ColumnDefinition Width="Auto" />
          <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>

					  
<TextBlock Text="{Binding FirstName}" />
        <TextBlock Text="{Binding LastName}"
                   Grid.Column="1"
                   Grid.Row="0"
                   Margin="5,0,0,0" />
        <TextBlock Text=" -> Error!!"
                   Foreground="Red"
                   Visibility=
      "{Binding InError, Converter={StaticResource REF_BoolToVisibilityConverter}}"
                   Grid.Column="2" />

      </Grid>
    </DataTemplate>

  </UserControl.Resources>
    <Grid x:Name="LayoutRoot"
          Background="White"
          Margin="10,10,10,10">
        <Grid.RowDefinitions>
           <RowDefinition Height="*" />
           <RowDefinition Height="Auto" />
           <RowDefinition Height="Auto" />
           <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <ListBox Grid.Row="0"
                 x:Name="lbx_Employees"
                 ItemTemplate="{StaticResource dtEmployee}"
                 SelectionChanged="lbx_Employees_SelectionChanged" />
        <Grid x:Name="grid_NewButton"
              Margin="0,2,0,0"
              Grid.Row="1"
              HorizontalAlignment="Right">
            <Button  x:Name="btn_New"
                     Click="btn_New_Click"
                     Content="New Employee" />
        </Grid>
    <input:ValidationSummary Grid.Row="2"
                             Margin="0,10,0,5" />
    <Border Grid.Row="3"
                Visibility="Collapsed"
                x:Name="border_EmployeeForm"
                Margin="0,2,0,0"
                BorderBrush="Black"
                BorderThickness="1"
                Padding="1,1,1,1">

					  

<Grid x:Name="grid_EmployeeForm">

                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="0.142*" />
                    <ColumnDefinition Width="0.379*" />
                    <ColumnDefinition Width="0.1*" />
                    <ColumnDefinition Width="0.097*" />
                    <ColumnDefinition Width="0.082*" />
                    <ColumnDefinition Width="0.2*" />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="0.10*" />
                    <RowDefinition Height="0.15*" />
                    <RowDefinition Height="0.15*" />
                    <RowDefinition Height="0.15*" />
                    <RowDefinition Height="0.45*" />
                </Grid.RowDefinitions>
                <TextBox HorizontalAlignment="Stretch"
                         Margin="1,1,1,1"
                         x:Name="tbxFName"
                         VerticalAlignment="Stretch"
                         Text=
                  "{Binding FirstName, Mode=TwoWay, UpdateSourceTrigger=Explicit}"
                         Grid.Row="1"
                         Width="Auto"
                         Grid.RowSpan="1"
                         Grid.ColumnSpan="2"
                         Grid.Column="1" />
                <TextBox HorizontalAlignment="Stretch"
                         Margin="1,1,1,1"
                         x:Name="tbxLName"
                         VerticalAlignment="Stretch"
                         Text=
                    "{Binding LastName, Mode=TwoWay,UpdateSourceTrigger=Explicit}"
                         Grid.Row="1"
                         Grid.Column="3"
                         Width="Auto"
                         Grid.RowSpan="1"
                         Grid.ColumnSpan="3" />
                <TextBlock HorizontalAlignment="Stretch"
                           Margin="1,1,1,1"
                           VerticalAlignment="Stretch"
                           Text="Last"
                           TextWrapping="Wrap"
                           Grid.RowSpan="1"

					  

Grid.Column="4"
                           Grid.ColumnSpan="2"
                           Height="Auto"
                           Width="Auto" />
                <TextBlock HorizontalAlignment="Center"
                           Margin="1,1,1,1"
                           VerticalAlignment="Center"
                           Text="First"
                           TextWrapping="Wrap"
                           Grid.RowSpan="1"
                           Grid.Column="1"
                           Width="Auto"
                           Height="Auto" />
                <TextBlock HorizontalAlignment="Center"
                           Margin="1,1,1,1"
                           VerticalAlignment="Stretch"
                           Text="Name"
                           TextWrapping="Wrap"
                           Grid.RowSpan="1"
                           Grid.Row="1"
                           Height="Auto"
                           Width="Auto" />
                <TextBlock HorizontalAlignment="Center"
                           Margin="1,1,1,1"
                           VerticalAlignment="Stretch"
                           Text="Street"
                           TextWrapping="Wrap"
                           Grid.Row="2"
                           Width="Auto" />
                <TextBox HorizontalAlignment="Stretch"
                         x:Name="tbxStreet"
                         VerticalAlignment="Stretch"
                         Text=
              "{Binding Address.Street, Mode=TwoWay, UpdateSourceTrigger=Explicit}"
                         Grid.Row="2"
                         Margin="1,1,1,1"
                         Grid.Column="1"
                         Grid.ColumnSpan="5"
                         Width="Auto" />
                <TextBlock HorizontalAlignment="Center"
                           VerticalAlignment="Stretch"
                           Text="City"
                           TextWrapping="Wrap"
                           Margin="1,1,1,1"
                           Grid.Row="3" />

					  

<TextBlock Text="State"
                           Margin="1,1,1,1"
                           TextWrapping="Wrap"
                           Grid.Column="2"
                           Grid.Row="3"
                           HorizontalAlignment="Center" />
                <TextBlock Text="Zip"
                           Margin="1,1,1,1"
                           TextWrapping="Wrap"
                           Grid.Column="4"
                           Grid.Row="3"
                           HorizontalAlignment="Center" />
                <TextBox HorizontalAlignment="Stretch"
                         x:Name="tbxCity"
                         Margin="1,1,1,1"
                         VerticalAlignment="Stretch"
                         Text=
                "{Binding Address.City, Mode=TwoWay, UpdateSourceTrigger=Explicit}"
                         Grid.Row="3"
                         Grid.Column="1" />

                <TextBox Background="Transparent"
                         Grid.Column="3"
                         Margin="1,1,1,1"
                         Grid.Row="3"
                         Text=
                "{Binding Address.State, Mode=TwoWay,UpdateSourceTrigger=Explicit,
                ValidatesOnExceptions=True,NotifyOnValidationError=True}"
                         x:Name="tbxState">
                </TextBox>


                <TextBox Background="Transparent"
                         Grid.Column="5"
                         Grid.Row="3"
                         Margin="1,1,1,1"
                         Text=
              "{Binding Address.ZipCode, Mode=TwoWay, UpdateSourceTrigger=Explicit,
                  ValidatesOnExceptions=True,NotifyOnValidationError=True}"
                         x:Name="tbxZipCode" />

                <TextBlock HorizontalAlignment="Center"
                           VerticalAlignment="Stretch"
                           Text="Phone"
                           Margin="1,1,1,1"

					  

TextWrapping="Wrap"
                           Grid.Row="4" />
                <TextBox Grid.Column="1"
                         Grid.Row="4"
                         Margin="1,1,1,1"
                         Text=
                    "{Binding PhoneNum, Mode=TwoWay, UpdateSourceTrigger=Explicit,
          ValidatesOnExceptions=True,NotifyOnValidationError=True}"
                         x:Name="tbxPhoneNum" />
                <StackPanel Orientation="Horizontal"
                            Grid.Column="4"
                            Margin="1,1,1,1"
                            Grid.ColumnSpan="2"
                            Grid.Row="4">
                    <Button Height="30.911"
                            Margin="2,2,2,0"
                            VerticalAlignment="Top"
                            Content="Save"
                            x:Name="btnSave"
                            Click="btnSave_Click" />
                    <Button Height="30.911"
                            Margin="2,2,2,0"
                            VerticalAlignment="Top"
                            Content="Close"
                            x:Name="btnClose"
                            Click="btnClose_Click" />
                </StackPanel>

            </Grid>
        </Border>
    </Grid>
</UserControl>

					  

Note the changes in XAML to the Binding declarations to set the UpdateSourceTrigger to Explicit. Listing 2 shows the codebehind.

Listing 2. Codebehind to MainPage
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace Recipe4_7
{

public partial class MainPage : UserControl
  {
    public MainPage()
    {
      InitializeComponent();

      //initialize the employee collection with some sample data
      ObservableCollection<Employee> empColl =
        new ObservableCollection<Employee>();

      empColl.Add(new Employee
      {
        FirstName = "Joe",
        LastName = "Duffin",
        PhoneNum = "2125551212",
        Address = new Address
        {
          Street = "2000 Mott Street",
          City = "New York",
          State = "NY",
          ZipCode = "10006"
        }
      });

      empColl.Add(new Employee
      {
        FirstName = "Alex",
        LastName = "Bleeker",
        PhoneNum = "7185551212",
        Address = new Address
        {
          Street = "11000 Clover Street",
          City = "New York",
          State = "NY",
          ZipCode = "10007"
        }
      });

empColl.Add(new Employee
      {
        FirstName = "Nelly",
        LastName = "Myers",
        PhoneNum = "7325551212",
        Address = new Address
        {

					  

Street = "12000 Fay Road",
          City = "New York",
          State = "NY",
          ZipCode = "10016"
        }
      });

      lbx_Employees.ItemsSource = empColl;

      this.BindingValidationError +=
        new System.EventHandler<ValidationErrorEventArgs>((s, e) =>
        {

          if (lbx_Employees.SelectedItem == null) return;
          //change the InError property of the currently selected Employee
          if (e.Action == ValidationErrorEventAction.Added)
            (lbx_Employees.SelectedItem as Employee).InError = true;
          else
            (lbx_Employees.SelectedItem as Employee).InError = false;

        });
    }

    private void btn_New_Click(object sender, RoutedEventArgs e)
    {
      //get the bound collection
      ObservableCollection<Employee> empColl =
        (ObservableCollection<Employee>)lbx_Employees.ItemsSource;
      //create and initialize a new Employee
      Employee newEmp = new Employee();
      newEmp.Address = new Address();
      //add it to the collection
      empColl.Add(newEmp);
//set the current selection to the newly added employee.
      //This will cause selection change to fire, and set the
      //datacontext for the form appropriately
      lbx_Employees.SelectedItem = newEmp;

    }

    private void lbx_Employees_SelectionChanged(object sender,
      SelectionChangedEventArgs e)
    {
      //set the datacontext of the form to the selected Employee
      grid_EmployeeForm.DataContext = (Employee)lbx_Employees.SelectedItem;

					  

//show the form
      border_EmployeeForm.Visibility = Visibility.Visible;
      grid_NewButton.Visibility = Visibility.Collapsed;
    }

    private void btnClose_Click(object sender, RoutedEventArgs e)
    {
      //hide the form
      border_EmployeeForm.Visibility = Visibility.Collapsed;
      grid_NewButton.Visibility = Visibility.Visible;
    }

    private void btnSave_Click(object sender, RoutedEventArgs e)
    {

      var bindingExpressions =
        grid_EmployeeForm.Children.OfType<TextBox>().
        Select((tbx)=>tbx.GetBindingExpression(TextBox.TextProperty));
      foreach (BindingExpression be in bindingExpressions) be.UpdateSource();
    }
  }
}

					  

Note the code in the Click event handler for btnSave. You perform a quick LINQ query on grid_EmployeeForm.Children collection to get access to the BindingExpressions for the Text property of all the children of type TextBox. You then proceed to iterate through the collection of BindingExpressions and call UpdateSource() on each of them.
Other  
  •  Silverlight : Data Binding - Validating Input for Bound Data
  •  Western Digital Black 4TB - One Of The Quickest Physical Drives
  •  Samsung 840 SSD 250GB - Most Of The Good Things
  •  SQL Server 2005 : Working with SQL Server Management Objects in Visual Studio (part 3) - Creating Backup-and-Restore Applications, Performing Programmatic DBCC Commands with SMO
  •  SQL Server 2005 : Working with SQL Server Management Objects in Visual Studio (part 2) - Retrieving Server Settings
  •  SQL Server 2005 : Working with SQL Server Management Objects in Visual Studio (part 1) - Iterating Through Available Servers
  •  SQL Server 2005 : Advanced OLAP - Roles
  •  SQL Server 2005 : Advanced OLAP - Translations
  •  SQL Server 2005 : Advanced OLAP - Perspectives
  •  Oracle Database 11g : Installing Oracle - Install the Oracle Software
  •  
    Top 10
    Free Mobile And Desktop Apps For Accessing Restricted Websites
    MASERATI QUATTROPORTE; DIESEL : Lure of Italian limos
    TOYOTA CAMRY 2; 2.5 : Camry now more comely
    KIA SORENTO 2.2CRDi : Fuel-sipping slugger
    How To Setup, Password Protect & Encrypt Wireless Internet Connection
    Emulate And Run iPad Apps On Windows, Mac OS X & Linux With iPadian
    Backup & Restore Game Progress From Any Game With SaveGameProgress
    Generate A Facebook Timeline Cover Using A Free App
    New App for Women ‘Remix’ Offers Fashion Advice & Style Tips
    SG50 Ferrari F12berlinetta : Prancing Horse for Lion City's 50th
    - Messages forwarded by Outlook rule go nowhere
    - Create and Deploy Windows 7 Image
    - How do I check to see if my exchange 2003 is an open relay? (not using a open relay tester tool online, but on the console)
    - Creating and using an unencrypted cookie in ASP.NET
    - Directories
    - Poor Performance on Sharepoint 2010 Server
    - SBS 2008 ~ The e-mail alias already exists...
    - Public to Private IP - DNS Changes
    - Send Email from Winform application
    - How to create a .mdb file from ms sql server database.......
    programming4us programming4us
    programming4us
     
     
    programming4us