Mobile Corner

Data Binding 101: Expression Syntax

Data-binding parameters that you can use when wiring up the contents of your Windows Phone application.

In the first and second articles in this series, I covered the basics of data binding and the use of value converters . In Part 3, I'm going to highlight a couple of other aspects you should be aware of related to binding syntax.

Source
First up is the Source parameter. Most data-binding expressions are relative to the DataContext of the current element. If there is no DataContext explicitly set on an element, it's inherited from its parent element (and so forth, up the hierarchy). However, in some cases, you don’t want to data bind to the current DataContext; instead, the Source property allows you to change the source object for the data-binding expression. In the following XAML, the DataContext attribute on the page is being data bound to the Main property on an application static resource, Locator.

<Application x:Class="DataBinding101.App"
    ...
    xmlns:local="clr-namespace:DataBinding101">
    <Application.Resources>
        <local:ViewModelLocator x:Key="Locator" />
    </Application.Resources>
    ...
</Application>


<phone:PhoneApplicationPage
    x:Class="DataBinding101.MainPage"
    ...
    DataContext="{Binding Main, Source={StaticResource Locator}}">

This example is a form of service locator pattern where by the page reaches out to the static resource, Locator, whose sole purpose is the creation and management of view models. The Main property will retrieve an instance of the view model appropriate for this page, illustrated in the following code snippet:

public class ViewModelLocator
{
    public MainViewModel Main
    {
        get
        {
            return new MainViewModel();
        }
    }
}

ElementName
The ElementName attribute can be used in a similar fashion to the Source attribute to change the source of the data-binding expression. However, the ElementName attribute is used to reference another visual element. For example, in the following code, the Background attribute of the Border is data bound to the Foreground attribute of the element with name TB_Name:

<TextBlock x:Name="TB_Name" Text="{Binding Name}" />
<Border Background="{Binding Foreground,ElementName=TB_Name}" Width="50" Height="50" />

This can be particularly useful when you’re working in the context of an item template for a list. In this case, your data-binding expressions are typically in relation to the item within the list. You can use the ElementName attribute to escape out to data bind to an attribute on an element elsewhere on the page.

StringFormat
Occasionally, when you want to display a value, you may wish to append a prefix, suffix or both. In the following XAML, the prefix "My Name is" has been inserted before the data bound value, and a full stop afterwards.

<TextBlock Text="{Binding Name,StringFormat='My Name is \{0\}.'}" />

The alternative is to use a number of Run elements, which gets quite messy.

<TextBlock> <Run Text="My Name is "/><Run Text="{Binding Name}"/><Run Text="."/></TextBlock>

ValidatesOnDataErrors
The ValidatesOnDataErrors attribute is useful in order to report validation errors when collecting data (i.e. with two-way data binding). In the following XAML, the Text attribute of the TextBox is data bound to the Name property using two-way data binding:

<TextBox Text="{Binding Name, Mode=TwoWay, ValidatesOnDataErrors=True}" 
         Style="{StaticResource DataErrorStyle}" />

By enabling the ValidatesOnDataErrors attribute, the data entered into the TextBox is validated when it's applied to the underlying data source, and any errors are reported to the user. Well, that’s the theory anyhow! Unfortunately, you have to do a couple of extra steps in order to get this to work.

First, the underlying data source has to implement the IDataError interface, which includes two properties for reporting validation errors. A basic implementation to the Person class is shown in Listing 1.

If you were to run this example and set a break point, if there was no text in the TextBlock, the message "Need to specify name" would be returned as an error. However, you wouldn’t see this displayed on the page because the default TextBox style doesn’t alter its appearance if there are validation errors. This can be fixed by adjusting the TextBox template. (In Microsoft Expression Blend, right-click on the TextBox and select Edit Template > Edit a Copy.) In the XAML in Listing 2, you’ll notice that an extra border has been added around the content, which is colored red for both the InvalidUnfocused and InvalidFocused states. (Note that this Style was referenced in the XAML for the TextBox earlier in this section.)

With this modified TextBox Style, and the IDataError implementation, if the user doesn’t enter a value into the TextBox, he will see a red border around the TextBox indicating a validation error. This is illustrated in Figure 1.

Figure 1. Validation States

One limitation of this implementation is that the validation doesn’t occur until the user taps away from the TextBox. At this point, the new value is applied to the underlying data source and the validation occurs. If you want to provide immediate feedback to the user, you can intercept the TextChanged event on the TextBox and force an update to the data binding.

<TextBox 
Text="{Binding Name, Mode=TwoWay, ValidatesOnDataErrors=True, UpdateSourceTrigger=Explicit}" 
         Style="{StaticResource DataErrorStyle}" 
         TextChanged="NameTextChanged" />

private void NameTextChanged(object sender, TextChangedEventArgs e)
{
    var binding = (sender as FrameworkElement).GetBindingExpression(TextBox.TextProperty);
    binding.UpdateSource();
}

Note that you’ve added the UpdateSourceTrigger parameter to the data-binding expression. You're explicitly calling the UpdateSource method on the data-binding expression for each change to the text in the TextBox, so it's unnecessary for the binding engine to update the source as well. Hence, you’ve set this parameter to Explicit.

I've covered a number of the data-binding parameters that you can use when wiring up the contents of your application. It’s important to remember that the more complex you make your data binding, the slower your application may perform. Of course, it’s always a trade off between the convenience offered by the data-binding expression—particularly, the support Expression Blend offers—and the speed and performance of the application.

About the Author

Nick Randolph runs Built to Roam, a consulting company that specializes in training, mentoring and assisting other companies build mobile applications. With a heritage in rich client applications for both the desktop and a variety of mobile platforms, Nick currently presents, writes and educates on the Windows Phone platform.

comments powered by Disqus

Featured

  • AI for GitHub Collaboration? Maybe Not So Much

    No doubt GitHub Copilot has been a boon for developers, but AI might not be the best tool for collaboration, according to developers weighing in on a recent social media post from the GitHub team.

  • Visual Studio 2022 Getting VS Code 'Command Palette' Equivalent

    As any Visual Studio Code user knows, the editor's command palette is a powerful tool for getting things done quickly, without having to navigate through menus and dialogs. Now, we learn how an equivalent is coming for Microsoft's flagship Visual Studio IDE, invoked by the same familiar Ctrl+Shift+P keyboard shortcut.

  • .NET 9 Preview 3: 'I've Been Waiting 9 Years for This API!'

    Microsoft's third preview of .NET 9 sees a lot of minor tweaks and fixes with no earth-shaking new functionality, but little things can be important to individual developers.

  • Data Anomaly Detection Using a Neural Autoencoder with C#

    Dr. James McCaffrey of Microsoft Research tackles the process of examining a set of source data to find data items that are different in some way from the majority of the source items.

  • What's New for Python, Java in Visual Studio Code

    Microsoft announced March 2024 updates to its Python and Java extensions for Visual Studio Code, the open source-based, cross-platform code editor that has repeatedly been named the No. 1 tool in major development surveys.

Subscribe on YouTube