WPF publish initial content (#1032)

* Add overview article for new WPF (#178)

* Remove previous WPF .NET 5 content

* Overview article

* New article: Create new WPF project (#183)

* Basic index file

* Finish article for new project.

* acro

* markdown fix

* Fix build errors

* fix code lang

* fix code lang

* Add differences article for WPF (#186)

* Fix VS version for create app

* Add differences article

* Minor

* fix overview styles code

* Add code langs for overview

* Port Window Overview WPF article (#1011)

* Add Window overview article

* Add TOC

* Remove temp code

* Fix headers

* Port final Windows related articles (#1015)

* Initial test commit

* Add system dialogs

* 75% complete

* Add images

* Fix linter

* Add to toc

* Add more howto

* Fix code

* Add get/set main window

* Add missing code

* Add to toc

* Fix warnings

* Fix warnings

* missing code

* Update see also

* fix xref

* Migrate wpf net core controls-styles articles (#1023)

* Migrate control-styles

* Fix links

* Fix links

* Port databinding article. (#1022)

* Migrated databinding overview

* update toc

* Fix links/snippets

* fix links

* Move to correct folder

* Port initial resources docs (#1026)

* initial resources docs

* Build errors

* Update dotnet-desktop-guide/net/wpf/systems/xaml-resources-overview.md

Co-authored-by: Genevieve Warren <[email protected]>

* Apply suggestions from code review

Co-authored-by: Genevieve Warren <[email protected]>

* Feedback

* Add app article

* Add system article

* Minor

* meta

* fix toc

* Apply suggestions from code review

Co-authored-by: Genevieve Warren <[email protected]>

Co-authored-by: Genevieve Warren <[email protected]>

* Add xaml article

* reformat redirect

* Redirects

* WPF update XAML article  (#1031)

* convert snippets

* minor edits

* minor

* Fix warnings

* Fixes #1028

* Fixes #1028

* Apply suggestions from code review

Co-authored-by: Genevieve Warren <[email protected]>

* update redirects

Co-authored-by: Genevieve Warren <[email protected]>

* minor updates to link

* Readd migration article

* Warning fixes

* Fix lint

* Minor updates

* Fix warnings for TOC/YML

* last warnings

Co-authored-by: Genevieve Warren <[email protected]>
This commit is contained in:
Andy (Steve) De George
2021-04-15 12:52:05 -07:00
committed by GitHub
co-authored by Genevieve Warren
parent a3b012ae99
commit ea8529f082
461 changed files with 8575 additions and 689 deletions
@@ -2,9 +2,8 @@
title: Data binding overview
description: Learn about the different data sources you can add to your project in Windows Presentation Foundation for .NET. Data sources can be bound to XAML elements to create dynamic apps.
author: adegeo
ms.date: 09/19/2019
ms.date: 03/25/2021
ms.author: adegeo
ms.topic: overview
dev_langs:
- "csharp"
- "vb"
@@ -28,7 +27,7 @@ A typical use of data binding is to place server or local configuration data int
For an example of data binding, take a look at the following app UI from the [Data Binding Demo][data-binding-demo], which displays a list of auction items.
![Data binding sample screenshot](./media/data-binding-overview/demo.png "DataBinding_DataBindingDemo")
:::image type="content" source="./media/index/demo.png" alt-text="Data binding sample screenshot":::
The app demonstrates the following features of data binding:
@@ -44,7 +43,7 @@ The app demonstrates the following features of data binding:
When the user selects the *Add Product* button, the following form comes up.
![Add Product Listing page](./media/data-binding-overview/demo-addproductlisting.png "DataBinding_Demo_AddProductListing")
:::image type="content" source="./media/index/demo-addproductlisting.png" alt-text="Add Product Listing page":::
The user can edit the fields in the form, preview the product listing using the short or detailed preview panes, and select `Submit` to add the new product listing. Any existing grouping, filtering and sorting settings will apply to the new entry. In this particular case, the item entered in the above image will be displayed as the second item within the *Computer* category.
@@ -56,7 +55,7 @@ Before going into the different features of data binding outlined above, we will
Regardless of what element you are binding and the nature of your data source, each binding always follows the model illustrated by the following figure.
![Diagram that shows the basic data binding model.](./media/data-binding-overview/basic-data-binding-diagram.png)
:::image type="content" source="./media/index/basic-data-binding-diagram.png" alt-text="Diagram that shows the basic data binding model.":::
As the figure shows, data binding is essentially the bridge between your binding target and your binding source. The figure demonstrates the following fundamental WPF data binding concepts:
@@ -85,11 +84,11 @@ You may want your app to enable users to change the data and propagate it back t
This figure illustrates the different types of data flow:
![Data binding data flow](./media/data-binding-overview/databinding-dataflow.png "DataBinding_DataFlow")
:::image type="content" source="./media/index/databinding-dataflow.png" alt-text="Data binding data flow":::
- <xref:System.Windows.Data.BindingMode.OneWay> binding causes changes to the source property to automatically update the target property, but changes to the target property are not propagated back to the source property. This type of binding is appropriate if the control being bound is implicitly read-only. For instance, you may bind to a source such as a stock ticker, or perhaps your target property has no control interface provided for making changes, such as a data-bound background color of a table. If there is no need to monitor the changes of the target property, using the <xref:System.Windows.Data.BindingMode.OneWay> binding mode avoids the overhead of the <xref:System.Windows.Data.BindingMode.TwoWay> binding mode.
- <xref:System.Windows.Data.BindingMode.TwoWay> binding causes changes to either the source property or the target property to automatically update the other. This type of binding is appropriate for editable forms or other fully interactive UI scenarios. Most properties default to <xref:System.Windows.Data.BindingMode.OneWay> binding, but some dependency properties (typically properties of user-editable controls such as the <xref:System.Windows.Controls.TextBox.Text?displayProperty=nameWithType> and [CheckBox.IsChecked](xref:System.Windows.Controls.Primitives.ToggleButton.IsChecked)) default to <xref:System.Windows.Data.BindingMode.TwoWay> binding. A programmatic way to determine whether a dependency property binds one-way or two-way by default is to get the property metadata with <xref:System.Windows.DependencyProperty.GetMetadata%2A?displayProperty=nameWithType> and then check the Boolean value of the <xref:System.Windows.FrameworkPropertyMetadata.BindsTwoWayByDefault%2A?displayProperty=nameWithType> property.
- <xref:System.Windows.Data.BindingMode.TwoWay> binding causes changes to either the source property or the target property to automatically update the other. This type of binding is appropriate for editable forms or other fully interactive UI scenarios. Most properties default to <xref:System.Windows.Data.BindingMode.OneWay> binding, but some dependency properties (typically properties of user-editable controls such as the <xref:System.Windows.Controls.TextBox.Text?displayProperty=nameWithType> and [CheckBox.IsChecked](xref:System.Windows.Controls.Primitives.ToggleButton.IsChecked) default to <xref:System.Windows.Data.BindingMode.TwoWay> binding. A programmatic way to determine whether a dependency property binds one-way or two-way by default is to get the property metadata with <xref:System.Windows.DependencyProperty.GetMetadata%2A?displayProperty=nameWithType> and then check the Boolean value of the <xref:System.Windows.FrameworkPropertyMetadata.BindsTwoWayByDefault%2A?displayProperty=nameWithType> property.
- <xref:System.Windows.Data.BindingMode.OneWayToSource> is the reverse of <xref:System.Windows.Data.BindingMode.OneWay> binding; it updates the source property when the target property changes. One example scenario is if you only need to reevaluate the source value from the UI.
@@ -105,13 +104,11 @@ Bindings that are <xref:System.Windows.Data.BindingMode.TwoWay> or <xref:System.
However, is your source value updated while you are editing the text or after you finish editing the text and the control loses focus? The <xref:System.Windows.Data.Binding.UpdateSourceTrigger?displayProperty=nameWithType> property determines what triggers the update of the source. The dots of the right arrows in the following figure illustrate the role of the <xref:System.Windows.Data.Binding.UpdateSourceTrigger?displayProperty=nameWithType> property.
![Diagram that shows the role of the UpdateSourceTrigger property.](./media/data-binding-overview/data-binding-updatesource-trigger.png)
:::image type="content" source="./media/index/data-binding-updatesource-trigger.png" alt-text="Diagram that shows the role of the UpdateSourceTrigger property.":::
If the `UpdateSourceTrigger` value is <xref:System.Windows.Data.UpdateSourceTrigger.PropertyChanged?displayProperty=nameWithType>, then the value pointed to by the right arrow of <xref:System.Windows.Data.BindingMode.TwoWay> or the <xref:System.Windows.Data.BindingMode.OneWayToSource> bindings is updated as soon as the target property changes. However, if the `UpdateSourceTrigger` value is <xref:System.Windows.Data.UpdateSourceTrigger.LostFocus>, then that value only is updated with the new value when the target property loses focus.
Similar to the <xref:System.Windows.Data.Binding.Mode%2A> property, different dependency properties have different default <xref:System.Windows.Data.Binding.UpdateSourceTrigger%2A> values. The default value for most dependency properties is <xref:System.Windows.Data.UpdateSourceTrigger.PropertyChanged>, while the `TextBox.Text` property has a default value of <xref:System.Windows.Data.UpdateSourceTrigger.LostFocus>. `PropertyChanged` means the source updates usually happen whenever the target property changes. Instant changes are fine for CheckBoxes and other simple controls. However, for text fields, updating after every keystroke can diminish performance and denies the user the usual opportunity to backspace and fix typing errors before committing to the new value.
See the <xref:System.Windows.Data.Binding.UpdateSourceTrigger%2A> property page for information about how to find the default value of a dependency property.
Similar to the <xref:System.Windows.Data.Binding.Mode%2A> property, different dependency properties have different default <xref:System.Windows.Data.Binding.UpdateSourceTrigger%2A> values. The default value for most dependency properties is <xref:System.Windows.Data.UpdateSourceTrigger.PropertyChanged>, which causes the source property's value to instantly change when the target property value is changed. Instant changes are fine for <xref:System.Windows.Controls.CheckBox> and other simple controls. However, for text fields, updating after every keystroke can diminish performance and denies the user the usual opportunity to backspace and fix typing errors before committing to the new value. For example, the `TextBox.Text` property defaults to the `UpdateSourceTrigger` value of <xref:System.Windows.Data.UpdateSourceTrigger.LostFocus> which causes the source value to change only when the control element loses focus, not when the `TextBox.Text` property is changed. See the <xref:System.Windows.Data.Binding.UpdateSourceTrigger%2A> property page for information about how to find the default value of a dependency property.
The following table provides an example scenario for each <xref:System.Windows.Data.Binding.UpdateSourceTrigger%2A> value using the <xref:System.Windows.Controls.TextBox> as an example.
@@ -123,19 +120,21 @@ The following table provides an example scenario for each <xref:System.Windows.D
For an example, see [How to: Control when the TextBox text updates the source](../../../framework/wpf/data/how-to-control-when-the-textbox-text-updates-the-source.md).
## Creating a binding
## Create a binding
To restate some of the concepts discussed in the previous sections, you establish a binding using the <xref:System.Windows.Data.Binding> object, and each binding usually has four components: a binding target, a target property, a binding source, and a path to the source value to use. This section discusses how to set up a binding.
When a databinding Binding sources are tied to the active <xref:System.Windows.FrameworkElement.DataContext%2A> for the element. Elements automatically inherit their `DataContext` if they've not explicitly defined one.
Consider the following example, in which the binding source object is a class named *MyData* that is defined in the *SDKSample* namespace. For demonstration purposes, *MyData* has a string property named *ColorName* whose value is set to "Red". Thus, this example generates a button with a red background.
[!code-xaml[BindNonTextProperty](./snippets/data-binding-overview/csharp/AutoConvertPropertyToColor.xaml#BindAutoConvertColor)]
:::code language="xaml" source="./snippets/data-binding-overview/csharp/AutoConvertPropertyToColor.xaml" id="BindAutoConvertColor":::
For more information on the binding declaration syntax and examples of how to set up a binding in code, see [Binding Declarations Overview](../../../framework/wpf/data/binding-declarations-overview.md).
If we apply this example to our basic diagram, the resulting figure looks like the following. This figure describes a <xref:System.Windows.Data.BindingMode.OneWay> binding because the Background property supports <xref:System.Windows.Data.BindingMode.OneWay> binding by default.
![Diagram that shows the data binding Background property.](./media/data-binding-overview/data-binding-button-background-example.png)
:::image type="content" source="./media/index/data-binding-button-background-example.png" alt-text="Diagram that shows the data binding Background property.":::
You may wonder why this binding works even though the *ColorName* property is of type string while the <xref:System.Windows.Controls.Control.Background%2A> property is of type <xref:System.Windows.Media.Brush>. This binding uses default type conversion, which is discussed in the [Data conversion](#data-conversion) section.
@@ -145,7 +144,7 @@ Notice that in the previous example, the binding source is specified by setting
There are several ways to specify the binding source object. Using the <xref:System.Windows.FrameworkElement.DataContext%2A> property on a parent element is useful when you are binding multiple properties to the same source. However, sometimes it may be more appropriate to specify the binding source on individual binding declarations. For the previous example, instead of using the <xref:System.Windows.FrameworkElement.DataContext%2A> property, you can specify the binding source by setting the <xref:System.Windows.Data.Binding.Source%2A?displayProperty=nameWithType> property directly on the binding declaration of the button, as in the following example.
[!code-xaml[BindNonTextPropertyCompactBinding](./snippets/data-binding-overview/csharp/AutoConvertPropertyToColor.xaml#BindAutoConvertColorCompactBinding)]
:::code language="xaml" source="./snippets/data-binding-overview/csharp/AutoConvertPropertyToColor.xaml" id="BindAutoConvertColorCompactBinding":::
Other than setting the <xref:System.Windows.FrameworkElement.DataContext%2A> property on an element directly, inheriting the <xref:System.Windows.FrameworkElement.DataContext%2A> value from an ancestor (such as the button in the first example), and explicitly specifying the binding source by setting the <xref:System.Windows.Data.Binding.Source%2A?displayProperty=nameWithType> property on the binding (such as the button the last example), you can also use the <xref:System.Windows.Data.Binding.ElementName?displayProperty=nameWithType> property or the <xref:System.Windows.Data.Binding.RelativeSource?displayProperty=nameWithType> property to specify the binding source. The <xref:System.Windows.Data.Binding.ElementName%2A> property is useful when you are binding to other elements in your app, such as when you are using a slider to adjust the width of a button. The <xref:System.Windows.Data.Binding.RelativeSource%2A> property is useful when the binding is specified in a <xref:System.Windows.Controls.ControlTemplate> or a <xref:System.Windows.Style>. For more information, see [How to: Specify the binding source](../../../framework/wpf/data/how-to-specify-the-binding-source.md).
@@ -157,7 +156,7 @@ For more information, see the <xref:System.Windows.Data.Binding.Path%2A> and <xr
Although we have emphasized that the <xref:System.Windows.Data.Binding.Path%2A> to the value to use is one of the four necessary components of a binding, in the scenarios that you want to bind to an entire object, the value to use would be the same as the binding source object. In those cases, it is applicable to not specify a <xref:System.Windows.Data.Binding.Path%2A>. Consider the following example.
[!code-xaml[EmptyBinding](./snippets/data-binding-overview/csharp/EmptyBinding.xaml#EmptyBinding)]
:::code language="xaml" source="./snippets/data-binding-overview/csharp/EmptyBinding.xaml" id="EmptyBinding":::
The above example uses the empty binding syntax: {Binding}. In this case, the <xref:System.Windows.Controls.ListBox> inherits the DataContext from a parent DockPanel element (not shown in this example). When the path is not specified, the default is to bind to the entire object. In other words, in this example, the path has been left out because we are binding the <xref:System.Windows.Controls.ItemsControl.ItemsSource%2A> property to the entire object. (See the [Binding to collections](#binding-to-collections) section for an in-depth discussion.)
@@ -171,8 +170,8 @@ Before getting into other features and usages of data binding, it is useful to i
Consider the following example, where `myDataObject` is an instance of the `MyData` class, `myBinding` is the source <xref:System.Windows.Data.Binding> object, and `MyData` is a defined class that contains a string property named `ColorName`. This example binds the text content of `myText`, an instance of <xref:System.Windows.Controls.TextBlock>, to `ColorName`.
[!code-csharp[CodeOnlyBinding](./snippets/data-binding-overview/csharp/ManualBinding.cs#CodeOnlyBinding)]
[!code-vb[CodeOnlyBinding](./snippets/data-binding-overview/vb/ManualBinding.vb#CodeOnlyBinding)]
:::code language="csharp" source="./snippets/data-binding-overview/csharp/ManualBinding.cs" id="CodeOnlyBinding":::
:::code language="vb" source="./snippets/data-binding-overview/vb/ManualBinding.vb" id="CodeOnlyBinding":::
You can use the same *myBinding* object to create other bindings. For example, you can use the *myBinding* object to bind the text content of a check box to *ColorName*. In that scenario, there will be two instances of <xref:System.Windows.Data.BindingExpression> sharing the *myBinding* object.
@@ -184,22 +183,22 @@ A <xref:System.Windows.Data.BindingExpression> object is returned by calling <xr
## Data conversion
In the [Creating a binding](#creating-a-binding) section, the button is red because its <xref:System.Windows.Controls.Control.Background%2A> property is bound to a string property with the value "Red". This string value works because a type converter is present on the <xref:System.Windows.Media.Brush> type to convert the string value to a <xref:System.Windows.Media.Brush>.
In the [Create a binding](#create-a-binding) section, the button is red because its <xref:System.Windows.Controls.Control.Background%2A> property is bound to a string property with the value "Red". This string value works because a type converter is present on the <xref:System.Windows.Media.Brush> type to convert the string value to a <xref:System.Windows.Media.Brush>.
Adding this information to the figure in the [Creating a Binding](#creating-a-binding) section looks like this.
Adding this information to the figure in the [Create a binding](#create-a-binding) section looks like this.
![Diagram that shows the data binding Default property.](./media/data-binding-overview/data-binding-button-default-conversion.png)
:::image type="content" source="./media/index/data-binding-button-default-conversion.png" alt-text="Diagram that shows the data binding Default property.":::
However, what if instead of having a property of type string your binding source object has a *Color* property of type <xref:System.Windows.Media.Color>? In that case, in order for the binding to work you would need to first turn the *Color* property value into something that the <xref:System.Windows.Controls.Control.Background%2A> property accepts. You would need to create a custom converter by implementing the <xref:System.Windows.Data.IValueConverter> interface, as in the following example.
[!code-csharp[CodeOnlyBinding](./snippets/data-binding-overview/csharp/ColorBrushConverter.cs#ColorBrushConverter)]
[!code-vb[CodeOnlyBinding](./snippets/data-binding-overview/vb/ColorBrushConverter.vb#ColorBrushConverter)]
:::code language="csharp" source="./snippets/data-binding-overview/csharp/ColorBrushConverter.cs" id="ColorBrushConverter":::
:::code language="vb" source="./snippets/data-binding-overview/vb/ColorBrushConverter.vb" id="ColorBrushConverter":::
See <xref:System.Windows.Data.IValueConverter> for more information.
Now the custom converter is used instead of default conversion, and our diagram looks like this.
![Diagram that shows the data binding custom converter.](./media/data-binding-overview/data-binding-converter-color-example.png)
:::image type="content" source="./media/index/data-binding-converter-color-example.png" alt-text="Diagram that shows the data binding custom converter.":::
To reiterate, default conversions may be available because of type converters that are present in the type being bound to. This behavior will depend on which type converters are available in the target. If in doubt, create your own converter.
@@ -219,7 +218,7 @@ A binding source object can be treated either as a single object whose propertie
Fortunately, our basic diagram still applies. If you are binding an <xref:System.Windows.Controls.ItemsControl> to a collection, the diagram looks like this.
![Diagram that shows the data binding ItemsControl object.](./media/data-binding-overview/data-binding-itemscontrol.png)
:::image type="content" source="./media/index/data-binding-itemscontrol.png" alt-text="Diagram that shows the data binding ItemsControl object.":::
As shown in this diagram, to bind an <xref:System.Windows.Controls.ItemsControl> to a collection object, <xref:System.Windows.Controls.ItemsControl.ItemsSource%2A?displayProperty=nameWithType> property is the property to use. You can think of `ItemsSource` as the content of the <xref:System.Windows.Controls.ItemsControl>. The binding is <xref:System.Windows.Data.BindingMode.OneWay> because the `ItemsSource` property supports `OneWay` binding by default.
@@ -245,11 +244,11 @@ Because views do not change the underlying source collections, each source colle
One way to create and use a view is to instantiate the view object directly and then use it as the binding source. For example, consider the [Data binding demo][data-binding-demo] app shown in the [What is data binding](#what-is-data-binding) section. The app is implemented such that the <xref:System.Windows.Controls.ListBox> binds to a view over the data collection instead of the data collection directly. The following example is extracted from the [Data binding demo][data-binding-demo] app. The <xref:System.Windows.Data.CollectionViewSource> class is the XAML proxy of a class that inherits from <xref:System.Windows.Data.CollectionView>. In this particular example, the <xref:System.Windows.Data.CollectionViewSource.Source%2A> of the view is bound to the *AuctionItems* collection (of type <xref:System.Collections.ObjectModel.ObservableCollection%601>) of the current app object.
[!code-xaml[CollectionView](./snippets/data-binding-overview/csharp/CollectionView.xaml#CollectionView)]
:::code language="xaml" source="./snippets/data-binding-overview/csharp/CollectionView.xaml" id="CollectionView":::
The resource *listingDataView* then serves as the binding source for elements in the app, such as the <xref:System.Windows.Controls.ListBox>.
[!code-xaml[ListBoxCollectionView](./snippets/data-binding-overview/csharp/CollectionView.xaml#ListBoxCollectionView)]
:::code language="xaml" source="./snippets/data-binding-overview/csharp/CollectionView.xaml" id="ListBoxCollectionView":::
To create another view for the same collection, you can create another <xref:System.Windows.Data.CollectionViewSource> instance and give it a different `x:Key` name.
@@ -277,20 +276,20 @@ As mentioned before, views can apply a sort order to a collection. As it exists
The following example shows the sorting logic of the "Sort by category and date" <xref:System.Windows.Controls.CheckBox> of the app UI in the [What is data binding](#what-is-data-binding) section.
[!code-csharp[AddSortChecked](./snippets/data-binding-overview/csharp/CollectionView.xaml.cs#AddSortChecked)]
[!code-vb[AddSortChecked](./snippets/data-binding-overview/vb/CollectionView.xaml.vb#AddSortChecked)]
:::code language="csharp" source="./snippets/data-binding-overview/csharp/CollectionView.xaml.cs" id="AddSortChecked":::
:::code language="vb" source="./snippets/data-binding-overview/vb/CollectionView.xaml.vb" id="AddSortChecked":::
#### Filtering
Views can also apply a filter to a collection, so that the view shows only a certain subset of the full collection. You might filter on a condition in the data. For instance, as is done by the app in the [What is data binding](#what-is-data-binding) section, the "Show only bargains" <xref:System.Windows.Controls.CheckBox> contains logic to filter out items that cost $25 or more. The following code is executed to set *ShowOnlyBargainsFilter* as the <xref:System.Windows.Data.CollectionViewSource.Filter> event handler when that <xref:System.Windows.Controls.CheckBox> is selected.
[!code-csharp[ListingViewFilter](./snippets/data-binding-overview/csharp/CollectionView.xaml.cs#ListingViewFilter)]
[!code-vb[ListingViewFilter](./snippets/data-binding-overview/vb/CollectionView.xaml.vb#ListingViewFilter)]
:::code language="csharp" source="./snippets/data-binding-overview/csharp/CollectionView.xaml.cs" id="ListingViewFilter":::
:::code language="vb" source="./snippets/data-binding-overview/vb/CollectionView.xaml.vb" id="ListingViewFilter":::
The *ShowOnlyBargainsFilter* event handler has the following implementation.
[!code-csharp[FilterEvent](./snippets/data-binding-overview/csharp/CollectionView.xaml.cs#FilterEvent)]
[!code-vb[FilterEvent](./snippets/data-binding-overview/vb/CollectionView.xaml.vb#FilterEvent)]
:::code language="csharp" source="./snippets/data-binding-overview/csharp/CollectionView.xaml.cs" id="FilterEvent":::
:::code language="vb" source="./snippets/data-binding-overview/vb/CollectionView.xaml.vb" id="FilterEvent":::
If you are using one of the <xref:System.Windows.Data.CollectionView> classes directly instead of <xref:System.Windows.Data.CollectionViewSource>, you would use the <xref:System.Windows.Data.CollectionView.Filter%2A> property to specify a callback. For an example, see [Filter Data in a View](../../../framework/wpf/data/how-to-filter-data-in-a-view.md).
@@ -300,8 +299,8 @@ Except for the internal class that views an <xref:System.Collections.IEnumerable
The following example shows the logic of the "Group by category" <xref:System.Windows.Controls.CheckBox>.
[!code-csharp[ListingGroupCheck](./snippets/data-binding-overview/csharp/CollectionView.xaml.cs#ListingGroupCheck)]
[!code-vb[ListingGroupCheck](./snippets/data-binding-overview/vb/CollectionView.xaml.vb#ListingGroupCheck)]
:::code language="csharp" source="./snippets/data-binding-overview/csharp/CollectionView.xaml.cs" id="ListingGroupCheck":::
:::code language="vb" source="./snippets/data-binding-overview/vb/CollectionView.xaml.vb" id="ListingGroupCheck":::
For another grouping example, see [Group Items in a ListView That Implements a GridView](../../../framework/wpf/controls/how-to-group-items-in-a-listview-that-implements-a-gridview.md).
@@ -331,7 +330,7 @@ The notion of a current item is useful not only for navigation of items in a col
You can implement the master-detail scenario simply by having two or more controls bound to the same view. The following example from the [Data binding demo][data-binding-demo] shows the markup of the <xref:System.Windows.Controls.ListBox> and the <xref:System.Windows.Controls.ContentControl> you see on the app UI in the [What is data binding](#what-is-data-binding) section.
[!code-xaml[ListBoxContentControl](./snippets/data-binding-overview/csharp/CollectionView.xaml#ListBoxContentControl)]
:::code language="xaml" source="./snippets/data-binding-overview/csharp/CollectionView.xaml" id="ListBoxContentControl":::
Notice that both of the controls are bound to the same source, the *listingDataView* static resource (see the definition of this resource in the [How to create a view section](#how-to-create-a-view)). This binding works because when a singleton object (the <xref:System.Windows.Controls.ContentControl> in this case) is bound to a collection view, it automatically binds to the <xref:System.Windows.Data.CollectionView.CurrentItem%2A> of the view. The <xref:System.Windows.Data.CollectionViewSource> objects automatically synchronize currency and selection. If your list control is not bound to a <xref:System.Windows.Data.CollectionViewSource> object as in this example, then you would need to set its <xref:System.Windows.Controls.Primitives.Selector.IsSynchronizedWithCurrentItem%2A> property to `true` for this to work.
@@ -343,13 +342,13 @@ You may have noticed that the above example uses a template. In fact, the data w
Without the use of data templates, our app UI in the [What is data binding](#what-is-data-binding) section would look like the following.
![Data Binding Demo without Data Templates](./media/data-binding-overview/demo-no-template.png)
:::image type="content" source="./media/index/demo-no-template.png" alt-text="Data Binding Demo without Data Templates":::
As shown in the example in the previous section, both the <xref:System.Windows.Controls.ListBox> control and the <xref:System.Windows.Controls.ContentControl> are bound to the entire collection object (or more specifically, the view over the collection object) of *AuctionItem*s. Without specific instructions of how to display the data collection, the <xref:System.Windows.Controls.ListBox> displays the string representation of each object in the underlying collection, and the <xref:System.Windows.Controls.ContentControl> displays the string representation of the object it is bound to.
To solve that problem, the app defines <xref:System.Windows.DataTemplate?text=DataTemplates>. As shown in the example in the previous section, the <xref:System.Windows.Controls.ContentControl> explicitly uses the *detailsProductListingTemplate* data template. The <xref:System.Windows.Controls.ListBox> control implicitly uses the following data template when displaying the *AuctionItem* objects in the collection.
[!code-xaml[AuctionItemDataTemplate](./snippets/data-binding-overview/csharp/CollectionView.xaml#AuctionItemDataTemplate)]
:::code language="xaml" source="./snippets/data-binding-overview/csharp/CollectionView.xaml" id="AuctionItemDataTemplate":::
With the use of those two DataTemplates, the resulting UI is the one shown in the [What is data binding](#what-is-data-binding) section. As you can see from that screenshot, in addition to letting you place data in your controls, DataTemplates allow you to define compelling visuals for your data. For example, <xref:System.Windows.DataTrigger>s are used in the above <xref:System.Windows.DataTemplate> so that *AuctionItem*s with *SpecialFeatures* value of *HighLight* would be displayed with an orange border and a star.
@@ -363,7 +362,7 @@ Most app that take user input need to have validation logic to ensure that the u
The WPF data binding model allows you to associate <xref:System.Windows.Data.Binding.ValidationRules%2A> with your <xref:System.Windows.Data.Binding> object. For example, the following example binds a <xref:System.Windows.Controls.TextBox> to a property named `StartPrice` and adds a <xref:System.Windows.Controls.ExceptionValidationRule> object to the <xref:System.Windows.Data.Binding.ValidationRules%2A?displayProperty=nameWithType> property.
[!code-xaml[TextboxStartPrice](./snippets/data-binding-overview/csharp/DataValidation.xaml#TextboxStartPrice)]
:::code language="xaml" source="./snippets/data-binding-overview/csharp/DataValidation.xaml" id="TextboxStartPrice":::
A <xref:System.Windows.Controls.ValidationRule> object checks whether the value of a property is valid. WPF has two types of built-in <xref:System.Windows.Controls.ValidationRule> objects:
@@ -373,12 +372,12 @@ A <xref:System.Windows.Controls.ValidationRule> object checks whether the value
You can also create your own validation rule by deriving from the <xref:System.Windows.Controls.ValidationRule> class and implementing the <xref:System.Windows.Controls.ValidationRule.Validate%2A> method. The following example shows the rule used by the *Add Product Listing* "Start Date" <xref:System.Windows.Controls.TextBox> from the [What is data binding](#what-is-data-binding) section.
[!code-csharp[FutureDateRule](./snippets/data-binding-overview/csharp/FutureDateRule.cs#FutureDateRule)]
[!code-vb[FutureDateRule](./snippets/data-binding-overview/vb/FutureDateRule.vb#FutureDateRule)]
:::code language="csharp" source="./snippets/data-binding-overview/csharp/FutureDateRule.cs" id="FutureDateRule":::
:::code language="vb" source="./snippets/data-binding-overview/vb/FutureDateRule.vb" id="FutureDateRule":::
The *StartDateEntryForm* <xref:System.Windows.Controls.TextBox> uses this *FutureDateRule*, as shown in the following example.
[!code-xaml[TextboxStartDate](./snippets/data-binding-overview/csharp/DataValidation.xaml#TextboxStartDate)]
:::code language="xaml" source="./snippets/data-binding-overview/csharp/DataValidation.xaml" id="TextboxStartDate":::
Because the <xref:System.Windows.Data.Binding.UpdateSourceTrigger%2A> value is <xref:System.Windows.Data.UpdateSourceTrigger.PropertyChanged>, the binding engine updates the source value on every keystroke, which means it also checks every rule in the <xref:System.Windows.Data.Binding.ValidationRules%2A> collection on every keystroke. We discuss this further in the Validation Process section.
@@ -386,21 +385,21 @@ Because the <xref:System.Windows.Data.Binding.UpdateSourceTrigger%2A> value is <
If the user enters an invalid value, you may want to provide some feedback about the error on the app UI. One way to provide such feedback is to set the <xref:System.Windows.Controls.Validation.ErrorTemplate%2A?displayProperty=nameWithType> attached property to a custom <xref:System.Windows.Controls.ControlTemplate>. As shown in the previous subsection, the *StartDateEntryForm* <xref:System.Windows.Controls.TextBox> uses an <xref:System.Windows.Controls.Validation.ErrorTemplate%2A> called *validationTemplate*. The following example shows the definition of *validationTemplate*.
[!code-xaml[ControlTemplate](./snippets/data-binding-overview/csharp/DataValidation.xaml#ControlTemplate)]
:::code language="xaml" source="./snippets/data-binding-overview/csharp/DataValidation.xaml" id="ControlTemplate":::
The <xref:System.Windows.Controls.AdornedElementPlaceholder> element specifies where the control being adorned should be placed.
In addition, you may also use a <xref:System.Windows.Controls.ToolTip> to display the error message. Both the *StartDateEntryForm* and the *StartPriceEntryForm*<xref:System.Windows.Controls.TextBox>es use the style *textStyleTextBox*, which creates a <xref:System.Windows.Controls.ToolTip> that displays the error message. The following example shows the definition of *textStyleTextBox*. The attached property <xref:System.Windows.Controls.Validation.HasError%2A?displayProperty=nameWithType> is `true` when one or more of the bindings on the properties of the bound element are in error.
[!code-xaml[TextBoxStyle](./snippets/data-binding-overview/csharp/DataValidation.xaml#TextBoxStyle)]
:::code language="xaml" source="./snippets/data-binding-overview/csharp/DataValidation.xaml" id="TextBoxStyle":::
With the custom <xref:System.Windows.Controls.Validation.ErrorTemplate%2A> and the <xref:System.Windows.Controls.ToolTip>, the *StartDateEntryForm* <xref:System.Windows.Controls.TextBox> looks like the following when there is a validation error.
![Data binding validation error](./media/data-binding-overview/demo-validation-date.png "DataBindingDemo_Validation")
:::image type="content" source="./media/index/demo-validation-date.png" alt-text="Data binding validation error for date":::
If your <xref:System.Windows.Data.Binding> has associated validation rules but you do not specify an <xref:System.Windows.Controls.Validation.ErrorTemplate%2A> on the bound control, a default <xref:System.Windows.Controls.Validation.ErrorTemplate%2A> will be used to notify users when there is a validation error. The default <xref:System.Windows.Controls.Validation.ErrorTemplate%2A> is a control template that defines a red border in the adorner layer. With the default <xref:System.Windows.Controls.Validation.ErrorTemplate%2A> and the <xref:System.Windows.Controls.ToolTip>, the UI of the *StartPriceEntryForm* <xref:System.Windows.Controls.TextBox> looks like the following when there is a validation error.
![Data binding validation error default](./media/data-binding-overview/demo-validation-price.png "DataBindingDemo_ValidationDefault")
:::image type="content" source="./media/index/demo-validation-price.png" alt-text="Data binding validation error for price":::
For an example of how to provide logic to validate all controls in a dialog box, see the Custom Dialog Boxes section in the [Dialog boxes overview](../../../framework/wpf/app-development/dialog-boxes-overview.md).
@@ -436,11 +435,7 @@ You can set the attached property <xref:System.Diagnostics.PresentationTraceSour
## See also
- <xref:System.Windows.Controls.DataErrorValidationRule>
- [Bind to the results of a LINQ query](../../../framework/wpf/data/how-to-bind-to-the-results-of-a-linq-query.md)
- [Data binding](../../../framework/wpf/advanced/optimizing-performance-data-binding.md)
- [Data binding demo][data-binding-demo]
- [How-to articles](../../../framework/wpf/data/data-binding-how-to-topics.md)
- [Bind to an ADO.NET data source](../../../framework/wpf/data/how-to-bind-to-an-ado-net-data-source.md)
- <xref:System.Windows.Controls.DataErrorValidationRule>
[data-binding-demo]: https://github.com/microsoft/WPF-Samples/tree/master/Sample%20Applications/DataBindingDemo "data binding demo app"

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

@@ -24,7 +24,7 @@
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
Value="{Binding (Validation.Errors).CurrentItem.ErrorContent, RelativeSource={RelativeSource Self}}" />
</Trigger>
</Style.Triggers>
</Style>
@@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net5.0-windows</TargetFramework>
<UseWpf>true</UseWpf>
</PropertyGroup>
@@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net5.0-windows</TargetFramework>
<RootNamespace>bindings</RootNamespace>
<UseWpf>true</UseWpf>
</PropertyGroup>