merge main branch

This commit is contained in:
CXWTool Service Account
2021-05-01 05:00:57 +00:00
26 changed files with 692 additions and 17 deletions
+8
View File
@@ -383,6 +383,14 @@
{
"source_path": "dotnet-desktop-guide/net/wpf/advanced/how-to-use-system-parameters-keys.md",
"redirect_url": "/dotnet/desktop/wpf/systems/xaml-resources-how-to-use-system?view=netdesktop-5.0"
},
{
"source_path": "dotnet-desktop-guide/net/wpf/migration/index.md",
"redirect_url": "/dotnet/desktop/wpf/migration/differences-from-net-framework?view=netdesktop-5.0"
},
{
"source_path": "dotnet-desktop-guide/net/wpf/data/how-to-specify-the-direction-of-the-binding.md",
"redirect_url": "/dotnet/desktop/wpf/data/binding-declarations-overview?view=netdesktop-5.0#binding-direction"
}
]
}
@@ -0,0 +1,158 @@
---
title: Binding declarations overview
description: Learn how to declare a data binding in XAML or code for your application development in Windows Presentation Foundation (WPF).
ms.date: 04/27/2021
author: adegeo
ms.author: adegeo
dev_langs:
- "csharp"
- "vb"
helpviewer_keywords:
- "markup extensions [WPF]"
- "data binding [WPF], declarations"
- "object element syntax [WPF]"
- "binding data [WPF], declarations"
- "syntax [WPF], object elements"
- "binding declarations [WPF]"
---
# Binding declarations overview (WPF .NET)
Typically, developers declare the bindings directly in the XAML markup of the UI elements they want to bind data to. However, you can also declare bindings in code. This article describes how to declare bindings in both XAML and in code.
## Prerequisites
Before reading this article, it's important that you're familiar with the concept and usage of markup extensions. For more information about markup extensions, see [Markup Extensions and WPF XAML](../../../framework/wpf/advanced/markup-extensions-and-wpf-xaml.md).
This article doesn't cover data binding concepts. For a discussion of data binding concepts, see [Data binding overview](index.md#basic-data-binding-concepts).
## Declare a binding in XAML
<xref:System.Windows.Data.Binding> is a markup extension. When you use the binding extension to declare a binding, the declaration consists of a series of clauses following the `Binding` keyword and separated by commas (,). The clauses in the binding declaration can be in any order and there are many possible combinations. The clauses are *Name*=*Value* pairs, where *Name* is the name of the <xref:System.Windows.Data.Binding> property and *Value* is the value you're setting for the property.
When creating binding declaration strings in markup, they must be attached to the specific dependency property of a target object. The following example shows how to bind the <xref:System.Windows.Controls.TextBox.Text%2A?displayProperty=nameWithType> property using the binding extension, specifying the <xref:System.Windows.Data.Binding.Source%2A> and <xref:System.Windows.Data.Binding.Path%2A> properties.
:::code language="xaml" source="./snippets/binding-declarations-overview/csharp/ExampleBinding.xaml" range="38":::
You can specify most of the properties of the <xref:System.Windows.Data.Binding> class this way. For more information about the binding extension and for a list of <xref:System.Windows.Data.Binding> properties that cannot be set using the binding extension, see the [Binding Markup Extension (.NET Framework)](../../../framework/wpf/advanced/binding-markup-extension.md) overview.
### Object element syntax
Object element syntax is an alternative to creating the binding declaration. In most cases, there's no particular advantage to using either the markup extension or the object element syntax. However, when the markup extension doesn't support your scenario, such as when your property value is of a non-string type for which no type conversion exists, you need to use the object element syntax.
The previous section demonstrated how to bind with a XAML extension. The following example demonstrates doing the same binding but uses object element syntax:
:::code language="xaml" source="./snippets/binding-declarations-overview/csharp/ExampleBinding.xaml" range="40-44":::
For more information about the different terms, see [XAML Syntax In Detail (.NET Framework)](../../../framework/wpf/advanced/xaml-syntax-in-detail.md).
### MultiBinding and PriorityBinding
<xref:System.Windows.Data.MultiBinding> and <xref:System.Windows.Data.PriorityBinding> don't support the XAML extension syntax. That's why you must use the object element syntax if you're declaring a <xref:System.Windows.Data.MultiBinding> or a <xref:System.Windows.Data.PriorityBinding> in XAML.
## Create a binding in code
Another way to specify a binding is to set properties directly on a <xref:System.Windows.Data.Binding> object in code, and then assign the binding to a property. The following example shows how to create a <xref:System.Windows.Data.Binding> object in code.
:::code language="csharp" source="./snippets/binding-declarations-overview/csharp/DataBindingCode.xaml.cs" id="SetBinding":::
:::code language="vb" source="./snippets/binding-declarations-overview/vb/DataBindingCode.xaml.vb" id="SetBinding":::
The previous code set the following on the binding:
- A path of the property on the data source object.
- The mode of the binding.
- The data source, in this case, a simple object instance representing a person.
- An optional converter that processes the value coming in from the data source object before it's assigned to the target property.
When the object you're binding is a <xref:System.Windows.FrameworkElement> or a <xref:System.Windows.FrameworkContentElement>, you can call the `SetBinding` method on your object directly instead of using <xref:System.Windows.Data.BindingOperations.SetBinding%2A?displayProperty=nameWithType>. For an example, see [How to: Create a Binding in Code](../../../framework/wpf/data/how-to-create-a-binding-in-code.md).
The previous example uses a simple data object type of `Person`. The following is the code for that object:
:::code language="csharp" source="./snippets/binding-declarations-overview/csharp/Person.cs" id="Person":::
:::code language="vb" source="./snippets/binding-declarations-overview/vb/Person.vb" id="Person":::
## Binding path syntax
Use the <xref:System.Windows.Data.Binding.Path%2A> property to specify the source value you want to bind to:
- In the simplest case, the <xref:System.Windows.Data.Binding.Path%2A> property value is the name of the property of the source object to use for the binding, such as `Path=PropertyName`.
- Subproperties of a property can be specified by a similar syntax as in C#. For instance, the clause `Path=ShoppingCart.Order` sets the binding to the subproperty `Order` of the object or property `ShoppingCart`.
- To bind to an attached property, place parentheses around the attached property. For example, to bind to the attached property <xref:System.Windows.Controls.DockPanel.Dock%2A?displayProperty=nameWithType>, the syntax is `Path=(DockPanel.Dock)`.
- Indexers of a property can be specified within square brackets following the property name where the indexer is applied. For instance, the clause `Path=ShoppingCart[0]` sets the binding to the index that corresponds to how your property's internal indexing handles the literal string "0". Nested indexers are also supported.
- Indexers and subproperties can be mixed in a `Path` clause; for example, `Path=ShoppingCart.ShippingInfo[MailingAddress,Street].`
- Inside indexers. You can have multiple indexer parameters separated by commas (`,`). The type of each parameter can be specified with parentheses. For example, you can have `Path="[(sys:Int32)42,(sys:Int32)24]"`, where `sys` is mapped to the `System` namespace.
- When the source is a collection view, the current item can be specified with a slash (`/`). For example, the clause `Path=/` sets the binding to the current item in the view. When the source is a collection, this syntax specifies the current item of the default collection view.
- Property names and slashes can be combined to traverse properties that are collections. For example, `Path=/Offices/ManagerName` specifies the current item of the source collection, which contains an `Offices` property that is also a collection. Its current item is an object that contains a `ManagerName` property.
- Optionally, a period (`.`) path can be used to bind to the current source. For example, `Text="{Binding}"` is equivalent to `Text="{Binding Path=.}"`.
### Escaping mechanism
- Inside indexers (`[ ]`), the caret character (`^`) escapes the next character.
- If you set <xref:System.Windows.Data.Binding.Path%2A> in XAML, you also need to escape (using XML entities) certain characters that are special to the XML language definition:
- Use `&amp;` to escape the character "`&`".
- Use `&gt;` to escape the end tag "`>`".
- Additionally, if you describe the entire binding in an attribute using the markup extension syntax, you need to escape (using backslash `\`) characters that are special to the WPF markup extension parser:
- Backslash (`\`) is the escape character itself.
- The equal sign (`=`) separates property name from property value.
- Comma (`,`) separates properties.
- The right curly brace (`}`) is the end of a markup extension.
## Binding direction
Use the <xref:System.Windows.Data.Binding.Mode%2A?displayProperty=nameWithType> property to specify the direction of the binding. The following modes are the available options for binding updates:
| Binding mode | Description |
|------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------|
| <xref:System.Windows.Data.BindingMode.TwoWay?displayProperty=nameWithType> | Updates the target property or the property whenever either the target property or the source property changes. |
| <xref:System.Windows.Data.BindingMode.OneWay?displayProperty=nameWithType> | Updates the target property only when the source property changes. |
| <xref:System.Windows.Data.BindingMode.OneTime?displayProperty=nameWithType> | Updates the target property only when the application starts or when the <xref:System.Windows.FrameworkElement.DataContext%2A> undergoes a change. |
| <xref:System.Windows.Data.BindingMode.OneWayToSource?displayProperty=nameWithType> | Updates the source property when the target property changes. |
| <xref:System.Windows.Data.BindingMode.Default?displayProperty=nameWithType> | Causes the default <xref:System.Windows.Data.Binding.Mode%2A> value of target property to be used. |
For more information, see the <xref:System.Windows.Data.BindingMode> enumeration.
The following example shows how to set the <xref:System.Windows.Data.Binding.Mode%2A> property:
```xaml
<TextBlock Name="IncomeText" Text="{Binding Path=TotalIncome, Mode=OneTime}" />
```
To detect source changes (applicable to <xref:System.Windows.Data.BindingMode.OneWay> and <xref:System.Windows.Data.BindingMode.TwoWay> bindings), the source must implement a suitable property change notification mechanism such as <xref:System.ComponentModel.INotifyPropertyChanged>. For more information, see [Providing change notifications](binding-sources-overview.md#provide-change-notifications).
For <xref:System.Windows.Data.BindingMode.TwoWay> or <xref:System.Windows.Data.BindingMode.OneWayToSource> bindings, you can control the timing of the source updates by setting the <xref:System.Windows.Data.Binding.UpdateSourceTrigger%2A> property. For more information, see <xref:System.Windows.Data.Binding.UpdateSourceTrigger%2A>.
## Default behaviors
The default behavior is as follows if not specified in the declaration:
- A default converter is created that tries to do a type conversion between the binding source value and the binding target value. If a conversion cannot be made, the default converter returns `null`.
- If you don't set <xref:System.Windows.Data.Binding.ConverterCulture%2A>, the binding engine uses the `Language` property of the binding target object. In XAML, this defaults to `en-US` or inherits the value from the root element (or any element) of the page, if one has been explicitly set.
- As long as the binding already has a data context (for example, the inherited data context coming from a parent element), and whatever item or collection being returned by that context is appropriate for binding without requiring further path modification, a binding declaration can have no clauses at all: `{Binding}`. This is often the way a binding is specified for data styling, where the binding acts upon a collection. For more information, see [Using Entire Objects as a Binding Source](../../../framework/wpf/data/binding-sources-overview.md#using-entire-objects-as-a-binding-source).
- The default <xref:System.Windows.Data.Binding.Mode%2A> varies between one-way and two-way depending on the dependency property that is being bound. You can always declare the binding mode explicitly to ensure that your binding has the desired behavior. In general, user-editable control properties, such as <xref:System.Windows.Controls.TextBox.Text%2A?displayProperty=nameWithType> and <xref:System.Windows.Controls.Primitives.RangeBase.Value%2A?displayProperty=nameWithType>, default to two-way bindings, but most other properties default to one-way bindings.
- The default <xref:System.Windows.Data.Binding.UpdateSourceTrigger%2A> value varies between <xref:System.Windows.Data.UpdateSourceTrigger.PropertyChanged> and <xref:System.Windows.Data.UpdateSourceTrigger.LostFocus> depending on the bound dependency property as well. The default value for most dependency properties is <xref:System.Windows.Data.UpdateSourceTrigger.PropertyChanged>, while the <xref:System.Windows.Controls.TextBox.Text%2A?displayProperty=nameWithType> property has a default value of <xref:System.Windows.Data.UpdateSourceTrigger.LostFocus>.
## See also
- [Data binding overview](index.md)
- [Binding sources overview](binding-sources-overview.md)
- [PropertyPath XAML Syntax (.NET Framework)](../../../framework/wpf/advanced/propertypath-xaml-syntax.md)
@@ -0,0 +1,106 @@
---
title: Binding sources overview
description: Discover the types of objects you can use as the binding source for your applications in Windows Presentation Foundation (WPF).
ms.date: 04/28/2021
author: adegeo
ms.author: adegeo
helpviewer_keywords:
- "binding data [WPF], binding sources"
- "data binding [WPF], binding source"
- "binding sources [WPF]"
---
# Binding sources overview (WPF .NET)
In data binding, the binding source object refers to the object you obtain data from. This article discusses the types of objects you can use as the binding source, like .NET CLR objects, XML, and <xref:System.Windows.DependencyObject> objects.
## Binding source types
Windows Presentation Foundation (WPF) data binding supports the following binding source types:
- **.NET common language runtime (CLR) objects**
You can bind to public properties, sub-properties, and indexers of any common language runtime (CLR) object. The binding engine uses CLR reflection to get the values of the properties. Objects that implement <xref:System.ComponentModel.ICustomTypeDescriptor> or have a registered <xref:System.ComponentModel.TypeDescriptionProvider> also work with the binding engine.
For more information about how to implement a class that can serve as a binding source, see [Implementing a binding source on your objects](#implement-a-binding-source-on-your-objects) later in this article.
- **Dynamic objects**
You can bind to available properties and indexers of an object that implements the <xref:System.Dynamic.IDynamicMetaObjectProvider> interface. If you can access the member in code, you can bind to it. For example, if a dynamic object enables you to access a member in code via `someObjet.AProperty`, you can bind to it by setting the binding path to `AProperty`.
- **ADO.NET objects**
You can bind to ADO.NET objects, such as <xref:System.Data.DataTable>. The ADO.NET <xref:System.Data.DataView> implements the <xref:System.ComponentModel.IBindingList> interface, which provides change notifications that the binding engine listens for.
- **XML objects**
You can bind to and run `XPath` queries on an <xref:System.Xml.XmlNode>, <xref:System.Xml.XmlDocument>, or <xref:System.Xml.XmlElement>. A convenient way to access XML data that is the binding source in markup is to use an <xref:System.Windows.Data.XmlDataProvider> object. For more information, see [Bind to XML Data Using an XMLDataProvider and XPath Queries (.NET Framework)](../../../framework/wpf/data/how-to-bind-to-xml-data-using-an-xmldataprovider-and-xpath-queries.md).
You can also bind to an <xref:System.Xml.Linq.XElement> or <xref:System.Xml.Linq.XDocument>, or bind to the results of queries run on objects of these types by using LINQ to XML. A convenient way to use LINQ to XML to access XML data that is the binding source in markup is to use an <xref:System.Windows.Data.ObjectDataProvider> object. For more information, see [Bind to XDocument, XElement, or LINQ for XML Query Results (.NET Framework)](../../../framework/wpf/data/how-to-bind-to-xdocument-xelement-or-linq-for-xml-query-results.md).
- **<xref:System.Windows.DependencyObject> objects**
You can bind to dependency properties of any <xref:System.Windows.DependencyObject>. For an example, see [Bind the Properties of Two Controls (.NET Framework)](../../../framework/wpf/data/how-to-bind-the-properties-of-two-controls.md).
## Implement a binding source on your objects
Your CLR objects can become binding sources. There are a few things to be aware of when implementing a class to serve as a binding source.
### Provide change notifications
If you're using either <xref:System.Windows.Data.BindingMode.OneWay> or <xref:System.Windows.Data.BindingMode.TwoWay> binding, implement a suitable "property changed" notification mechanism. The recommended mechanism is for the CLR or dynamic class to implement the <xref:System.ComponentModel.INotifyPropertyChanged> interface. For more information, see [How to: Implement Property Change Notification (.NET Framework)](../../../framework/wpf/data/how-to-implement-property-change-notification.md).
There are two ways to notify a subscriber of a property change:
01. Implement the <xref:System.ComponentModel.INotifyPropertyChanged> interface.
This is the recommended mechanism for notifications. The <xref:System.ComponentModel.INotifyPropertyChanged> supplies the <xref:System.ComponentModel.INotifyPropertyChanged.PropertyChanged> event, which the binding system respects. By raising this event, and providing the name of the property that changed, you'll notify a binding target of the change.
01. Implement the `PropertyChanged` pattern.
Each property that needs to notify a binding target that it's changed, has a corresponding `PropertyNameChanged` event, where `PropertyName` is the name of the property. You raise the event every time the property changes.
If your binding source implements one of these notification mechanisms, target updates happen automatically. If for any reason your binding source doesn't provide the proper property changed notifications, you can use the <xref:System.Windows.Data.BindingExpression.UpdateTarget%2A> method to update the target property explicitly.
### Other characteristics
The following list provides other important points to note:
- Data objects that serve as binding sources can be declared in XAML as resources, provided they have a **parameterless constructor**. Otherwise, you must create the data object in code and directly assign it to either the data context of your XAML object tree, or as the binding source of binding.
- The properties you use as binding source properties must be public properties of your class. Explicitly defined interface properties can't be accessed for binding purposes, nor can protected, private, internal, or virtual properties that have no base implementation.
- You can't bind to public fields.
- The type of the property declared in your class is the type that is passed to the binding. However, the type ultimately used by the binding depends on the type of the binding target property, not of the binding source property. If there's a difference in type, you might want to write a converter to handle how your custom property is initially passed to the binding. For more information, see <xref:System.Windows.Data.IValueConverter>.
## Entire objects as a binding source
You can use an entire object as a binding source. Specify a binding source by using the <xref:System.Windows.Data.Binding.Source%2A> or the <xref:System.Windows.FrameworkElement.DataContext%2A> property, and then provide a blank binding declaration: `{Binding}`. Scenarios in which this is useful include binding to objects that are of type string, binding to objects with multiple properties you're interested in, or binding to collection objects. For an example of binding to an entire collection object, see [How to Use the Master-Detail Pattern with Hierarchical Data (.NET Framework)](../../../framework/wpf/data/how-to-use-the-master-detail-pattern-with-hierarchical-data.md).
You may need to apply custom logic so that the data is meaningful to your bound target property. The custom logic may be in the form of a custom converter or a <xref:System.Windows.DataTemplate>. For more information about converters, see [Data conversion](index.md#data-conversion). For more information about data templates, see [Data Templating Overview (.NET Framework)](../../../framework/wpf/data/data-templating-overview.md).
## Collection objects as a binding source
Often, the object you want to use as the binding source is a collection of custom objects. Each object serves as the source for one instance of a repeated binding. For example, you might have a `CustomerOrders` collection that consists of `CustomerOrder` objects, where your application iterates over the collection to determine how many orders exist and the data contained in each order.
You can enumerate over any collection that implements the <xref:System.Collections.IEnumerable> interface. However, to set up dynamic bindings so that insertions or deletions in the collection update the UI automatically, the collection must implement the <xref:System.Collections.Specialized.INotifyCollectionChanged> interface. This interface exposes an event that must be raised whenever the underlying collection changes.
The <xref:System.Collections.ObjectModel.ObservableCollection%601> class is a built-in implementation of a data collection that exposes the <xref:System.Collections.Specialized.INotifyCollectionChanged> interface. The individual data objects within the collection must satisfy the requirements described in the preceding sections. For an example, see [How to Create and Bind to an ObservableCollection (.NET Framework)](../../../framework/wpf/data/how-to-create-and-bind-to-an-observablecollection.md). Before you implement your own collection, consider using <xref:System.Collections.ObjectModel.ObservableCollection%601> or one of the existing collection classes, such as <xref:System.Collections.Generic.List%601>, <xref:System.Collections.ObjectModel.Collection%601>, and <xref:System.ComponentModel.BindingList%601>, among many others.
When you specify a collection as a binding source, WPF doesn't bind directly to the collection. Instead, WPF actually binds to the collection's default view. For information about default views, see [Using a default view](index.md#using-a-default-view).
If you have an advanced scenario and you want to implement your own collection, consider using the <xref:System.Collections.IList> interface. This interface provides a non-generic collection of objects that can be individually accessed by index, which can improve performance.
## Permission requirements in data binding
Unlike .NET Framework, .NET 5+ (and .NET Core 3.1) runs with full-trust security. All data binding runs with the same access as the user running the application.
## See also
- <xref:System.Windows.Data.ObjectDataProvider>
- <xref:System.Windows.Data.XmlDataProvider>
- [Data binding overview](index.md)
- [Binding sources overview](binding-sources-overview.md)
- [Overview of WPF data binding with LINQ to XML (.NET Framework)](../../../framework/wpf/data/wpf-data-binding-with-linq-to-xml-overview.md)
- [Optimizing Performance: Data Binding (.NET Framework)](../../../framework/wpf/advanced/optimizing-performance-data-binding.md)
+18 -17
View File
@@ -55,7 +55,7 @@ As the figure shows, data binding is essentially the bridge between your binding
- Binding sources aren't restricted to custom .NET objects.
Although not shown in the figure, it should be noted that the binding source object isn't restricted to being a custom .NET object. WPF data binding supports data in the form of .NET objects, XML, and even XAML element objects. To provide some examples, your binding source may be a <xref:System.Windows.UIElement>, any list object, an ADO.NET or Web Services object, or an XmlNode that contains your XML data. For more information, see [Binding sources overview](../../../framework/wpf/data/binding-sources-overview.md).
Although not shown in the figure, it should be noted that the binding source object isn't restricted to being a custom .NET object. WPF data binding supports data in the form of .NET objects, XML, and even XAML element objects. To provide some examples, your binding source may be a <xref:System.Windows.UIElement>, any list object, an ADO.NET or Web Services object, or an XmlNode that contains your XML data. For more information, see [Binding sources overview](binding-sources-overview.md).
It's important to remember that when you're establishing a binding, you're binding a binding target *to* a binding source. For example, if you're displaying some underlying XML data in a <xref:System.Windows.Controls.ListBox> using data binding, you're binding your `ListBox` to the XML data.
@@ -87,7 +87,7 @@ This figure illustrates the different types of data flow:
- Not illustrated in the figure is <xref:System.Windows.Data.BindingMode.OneTime> binding, which causes the source property to initialize the target property but doesn't propagate subsequent changes. If the data context changes or the object in the data context changes, the change is *not* reflected in the target property. This type of binding is appropriate if either a snapshot of the current state is appropriate or the data is truly static. This type of binding is also useful if you want to initialize your target property with some value from a source property and the data context isn't known in advance. This mode is essentially a simpler form of <xref:System.Windows.Data.BindingMode.OneWay> binding that provides better performance in cases where the source value doesn't change.
To detect source changes (applicable to <xref:System.Windows.Data.BindingMode.OneWay> and <xref:System.Windows.Data.BindingMode.TwoWay> bindings), the source must implement a suitable property change notification mechanism such as <xref:System.ComponentModel.INotifyPropertyChanged>. See [How to: Implement property change notification](../../../framework/wpf/data/how-to-implement-property-change-notification.md) for an example of an <xref:System.ComponentModel.INotifyPropertyChanged> implementation.
To detect source changes (applicable to <xref:System.Windows.Data.BindingMode.OneWay> and <xref:System.Windows.Data.BindingMode.TwoWay> bindings), the source must implement a suitable property change notification mechanism such as <xref:System.ComponentModel.INotifyPropertyChanged>. See [How to: Implement property change notification (.NET Framework)](../../../framework/wpf/data/how-to-implement-property-change-notification.md) for an example of an <xref:System.ComponentModel.INotifyPropertyChanged> implementation.
The <xref:System.Windows.Data.Binding.Mode?displayProperty=nameWithType> property provides more information about binding modes and an example of how to specify the direction of a binding.
@@ -111,7 +111,7 @@ The following table provides an example scenario for each <xref:System.Windows.D
| `PropertyChanged` | As you type into the <xref:System.Windows.Controls.TextBox>. | TextBox controls in a chat room window. |
| `Explicit` | When the app calls <xref:System.Windows.Data.BindingExpression.UpdateSource%2A>. | TextBox controls in an editable form (updates the source values only when the user presses the submit button). |
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).
For an example, see [How to: Control when the TextBox text updates the source (.NET Framework)](../../../framework/wpf/data/how-to-control-when-the-textbox-text-updates-the-source.md).
## Example of data binding
@@ -151,7 +151,7 @@ Consider the following example, in which the binding source object is a class na
:::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).
For more information on the binding declaration syntax and examples of how to set up a binding in code, see [Binding declarations overview](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.
@@ -167,7 +167,7 @@ There are several ways to specify the binding source object. Using the <xref:Sys
:::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're binding to other elements in your app, such as when you're 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).
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're binding to other elements in your app, such as when you're 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 [Binding sources overview](binding-sources-overview.md).
### Specifying the path to the value
@@ -198,9 +198,8 @@ You can use the same *myBinding* object to create other bindings. For example, y
A <xref:System.Windows.Data.BindingExpression> object is returned by calling <xref:System.Windows.Data.BindingOperations.GetBindingExpression%2A> on a data-bound object. The following articles demonstrate some of the usages of the <xref:System.Windows.Data.BindingExpression> class:
- [Get the binding object from a bound target property](../../../framework/wpf/data/how-to-get-the-binding-object-from-a-bound-target-property.md)
- [Control When the TextBox text updates the source](../../../framework/wpf/data/how-to-control-when-the-textbox-text-updates-the-source.md)
- [Get the binding object from a bound target property (.NET Framework)](../../../framework/wpf/data/how-to-get-the-binding-object-from-a-bound-target-property.md)
- [Control When the TextBox text updates the source (.NET Framework)](../../../framework/wpf/data/how-to-control-when-the-textbox-text-updates-the-source.md)
## Data conversion
@@ -247,7 +246,7 @@ As shown in this diagram, to bind an <xref:System.Windows.Controls.ItemsControl>
You can enumerate over any collection that implements the <xref:System.Collections.IEnumerable> interface. However, to set up dynamic bindings so that insertions or deletions in the collection update the UI automatically, the collection must implement the <xref:System.Collections.Specialized.INotifyCollectionChanged> interface. This interface exposes an event that should be raised whenever the underlying collection changes.
WPF provides the <xref:System.Collections.ObjectModel.ObservableCollection%601> class, which is a built-in implementation of a data collection that exposes the <xref:System.Collections.Specialized.INotifyCollectionChanged> interface. To fully support transferring data values from source objects to targets, each object in your collection that supports bindable properties must also implement the <xref:System.ComponentModel.INotifyPropertyChanged> interface. For more information, see [Binding sources overview](../../../framework/wpf/data/binding-sources-overview.md).
WPF provides the <xref:System.Collections.ObjectModel.ObservableCollection%601> class, which is a built-in implementation of a data collection that exposes the <xref:System.Collections.Specialized.INotifyCollectionChanged> interface. To fully support transferring data values from source objects to targets, each object in your collection that supports bindable properties must also implement the <xref:System.ComponentModel.INotifyPropertyChanged> interface. For more information, see [Binding sources overview](binding-sources-overview.md).
Before implementing your own collection, consider using <xref:System.Collections.ObjectModel.ObservableCollection%601> or one of the existing collection classes, such as <xref:System.Collections.Generic.List%601>, <xref:System.Collections.ObjectModel.Collection%601>, and <xref:System.ComponentModel.BindingList%601>, among many others. If you have an advanced scenario and want to implement your own collection, consider using <xref:System.Collections.IList>, which provides a non-generic collection of objects that can be individually accessed by the index, and thus provides the best performance.
@@ -285,7 +284,7 @@ The following table shows what view data types are created as the default collec
Specifying a collection view as a binding source is one way to create and use a collection view. WPF also creates a default collection view for every collection used as a binding source. If you bind directly to a collection, WPF binds to its default view. This default view is shared by all bindings to the same collection, so a change made to a default view by one bound control or code (such as sorting or a change to the current item pointer, discussed later) is reflected in all other bindings to the same collection.
To get the default view, you use the <xref:System.Windows.Data.CollectionViewSource.GetDefaultView%2A> method. For an example, see [Get the default view of a data collection](../../../framework/wpf/data/how-to-get-the-default-view-of-a-data-collection.md).
To get the default view, you use the <xref:System.Windows.Data.CollectionViewSource.GetDefaultView%2A> method. For an example, see [Get the default view of a data collection (.NET Framework)](../../../framework/wpf/data/how-to-get-the-default-view-of-a-data-collection.md).
#### Collection views with ADO.NET DataTables
@@ -293,7 +292,7 @@ To improve performance, collection views for ADO.NET <xref:System.Data.DataTable
#### Sorting
As mentioned before, views can apply a sort order to a collection. As it exists in the underlying collection, your data may or may not have a relevant, inherent order. The view over the collection allows you to impose an order, or change the default order, based on comparison criteria that you supply. Because it's a client-based view of the data, a common scenario is that the user might want to sort columns of tabular data per the value that the column corresponds to. Using views, this user-driven sort can be applied, again without making any changes to the underlying collection or even having to requery for the collection content. For an example, see [Sort a GridView column when a header is clicked](../../../framework/wpf/controls/how-to-sort-a-gridview-column-when-a-header-is-clicked.md).
As mentioned before, views can apply a sort order to a collection. As it exists in the underlying collection, your data may or may not have a relevant, inherent order. The view over the collection allows you to impose an order, or change the default order, based on comparison criteria that you supply. Because it's a client-based view of the data, a common scenario is that the user might want to sort columns of tabular data per the value that the column corresponds to. Using views, this user-driven sort can be applied, again without making any changes to the underlying collection or even having to requery for the collection content. For an example, see [Sort a GridView column when a header is clicked (.NET Framework)](../../../framework/wpf/controls/how-to-sort-a-gridview-column-when-a-header-is-clicked.md).
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.
@@ -312,7 +311,7 @@ The *ShowOnlyBargainsFilter* event handler has the following implementation.
:::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're 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).
If you're 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 (.NET Framework)](../../../framework/wpf/data/how-to-filter-data-in-a-view.md).
#### Grouping
@@ -323,11 +322,11 @@ The following example shows the logic of the "Group by category" <xref:System.Wi
:::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).
For another grouping example, see [Group Items in a ListView That Implements a GridView (.NET Framework)](../../../framework/wpf/controls/how-to-group-items-in-a-listview-that-implements-a-gridview.md).
#### Current item pointers
Views also support the notion of a current item. You can navigate through the objects in a collection view. As you navigate, you're moving an item pointer that allows you to retrieve the object that exists at that particular location in the collection. For an example, see [Navigate through the objects in a data CollectionView](../../../framework/wpf/data/how-to-navigate-through-the-objects-in-a-data-collectionview.md).
Views also support the notion of a current item. You can navigate through the objects in a collection view. As you navigate, you're moving an item pointer that allows you to retrieve the object that exists at that particular location in the collection. For an example, see [Navigate through the objects in a data CollectionView (.NET Framework)](../../../framework/wpf/data/how-to-navigate-through-the-objects-in-a-data-collectionview.md).
Because WPF binds to a collection only by using a view (either a view you specify, or the collection's default view), all bindings to collections have a current item pointer. When binding to a view, the slash ("/") character in a `Path` value designates the current item of the view. In the following example, the data context is a collection view. The first line binds to the collection. The second line binds to the current item in the collection. The third line binds to the `Description` property of the current item in the collection.
@@ -355,7 +354,7 @@ You can implement the master-detail scenario simply by having two or more contro
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 isn't 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.
For other examples, see [Bind to a collection and display information based on selection](../../../framework/wpf/data/how-to-bind-to-a-collection-and-display-information-based-on-selection.md) and [Use the master-detail pattern with hierarchical data](../../../framework/wpf/data/how-to-use-the-master-detail-pattern-with-hierarchical-data.md).
For other examples, see [Bind to a collection and display information based on selection (.NET Framework)](../../../framework/wpf/data/how-to-bind-to-a-collection-and-display-information-based-on-selection.md) and [Use the master-detail pattern with hierarchical data (.NET Framework)](../../../framework/wpf/data/how-to-use-the-master-detail-pattern-with-hierarchical-data.md).
You may have noticed that the above example uses a template. In fact, the data would not be displayed the way we wish without the use of templates (the one explicitly used by the <xref:System.Windows.Controls.ContentControl> and the one implicitly used by the <xref:System.Windows.Controls.ListBox>). We now turn to data templating in the next section.
@@ -373,7 +372,7 @@ To solve that problem, the app defines <xref:System.Windows.DataTemplate?text=Da
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.
For more information about data templates, see the [Data templating overview](../../../framework/wpf/data/data-templating-overview.md).
For more information about data templates, see the [Data templating overview (.NET Framework)](../../../framework/wpf/data/data-templating-overview.md).
## Data validation
@@ -422,7 +421,7 @@ If your <xref:System.Windows.Data.Binding> has associated validation rules but y
:::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).
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](../windows/dialog-boxes-overview.md).
### Validation process
@@ -457,6 +456,8 @@ You can set the attached property <xref:System.Diagnostics.PresentationTraceSour
## See also
- [Data binding demo][data-binding-demo]
- [Binding declarations overview](binding-declarations-overview.md)
- [Binding sources overview](binding-sources-overview.md)
- <xref:System.Windows.Controls.DataErrorValidationRule>
[data-binding-demo]: https://github.com/microsoft/WPF-Samples/tree/master/Sample%20Applications/DataBindingDemo "data binding demo app"
@@ -0,0 +1,9 @@
<Application x:Class="ArticleExample.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ArticleExample"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
namespace ArticleExample
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net5.0-windows</TargetFramework>
<UseWPF>true</UseWPF>
</PropertyGroup>
</Project>
@@ -0,0 +1,10 @@
using System.Windows;
[assembly:ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
@@ -0,0 +1,12 @@
<Window x:Class="ArticleExample.DataBindingCode"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DataBinding in code" SizeToContent="WidthAndHeight"
Loaded="Window_Loaded">
<Border>
<StackPanel Width="300" Margin="35">
<Label>Person name:</Label>
<TextBlock x:Name="NameBlock" Margin="10,0,0,0" />
</StackPanel>
</Border>
</Window>
@@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using System.Globalization;
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.Shapes;
namespace ArticleExample
{
/// <summary>
/// Interaction logic for DataBindingCode.xaml
/// </summary>
public partial class DataBindingCode : Window
{
// <Converter>
private class NameConverter : IValueConverter
{
private static NameConverter _instance = new();
public static NameConverter Instance => _instance;
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) =>
$"[[ {value} ]]";
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
value.ToString().Trim('[', ']', ' ');
}
// </Converter>
public DataBindingCode()
{
InitializeComponent();
}
// <SetBinding>
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// Make a new data source object
var personDetails = new Person()
{
Name = "John",
Birthdate = DateTime.Parse("2001-02-03")
};
// New binding object using the path of 'Name' for whatever source object is used
var nameBindingObject = new Binding("Name");
// Configure the binding
nameBindingObject.Mode = BindingMode.OneWay;
nameBindingObject.Source = personDetails;
nameBindingObject.Converter = NameConverter.Instance;
nameBindingObject.ConverterCulture = new CultureInfo("en-US");
// Set the binding to a target object. The TextBlock.Name property on the NameBlock UI element
BindingOperations.SetBinding(NameBlock, TextBlock.TextProperty, nameBindingObject);
}
// </SetBinding>
}
}
@@ -0,0 +1,47 @@
<Window x:Class="ArticleExample.ExampleBinding"
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:ArticleExample"
mc:Ignorable="d"
SizeToContent="WidthAndHeight"
Title="Simple Data Binding Sample">
<Window.Resources>
<local:Person x:Key="myDataSource" Name="Joe" Birthdate="2000-02-03"/>
<Style TargetType="{x:Type Label}">
<Setter Property="FontSize" Value="12"/>
</Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Width" Value="100"/>
<Setter Property="Height" Value="25"/>
</Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Width" Value="100"/>
<Setter Property="Height" Value="25"/>
<Setter Property="Padding" Value="3"/>
</Style>
</Window.Resources>
<Border Margin="5" BorderBrush="Aqua" BorderThickness="1" Padding="8" CornerRadius="3">
<StackPanel Width="200" Margin="35">
<Label>Enter a Name:</Label>
<TextBox>
<TextBox.Text>
<Binding Source="{StaticResource myDataSource}"
Path="PersonName"
UpdateSourceTrigger="PropertyChanged"/>
</TextBox.Text>
</TextBox>
<Label>The name you entered:</Label>
<TextBlock Text="{Binding Source={StaticResource myDataSource}, Path=Name}"/>
<Label>The name you entered:</Label>
<TextBlock>
<TextBlock.Text>
<Binding Source="{StaticResource myDataSource}" Path="Name"/>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</Border>
</Window>
@@ -0,0 +1,27 @@
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.Shapes;
namespace ArticleExample
{
/// <summary>
/// Interaction logic for ExampleBinding.xaml
/// </summary>
public partial class ExampleBinding : Window
{
public ExampleBinding()
{
InitializeComponent();
}
}
}
@@ -0,0 +1,15 @@
<Window x:Class="ArticleExample.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:ArticleExample"
mc:Ignorable="d"
SizeToContent="WidthAndHeight"
Title="Simple Data Binding Sample">
<StackPanel Width="200" Margin="35">
<Button Click="ShowDataBindingCode_Click">DataBinding in code</Button>
<Button Click="ShowBasicDataBinding_Click">Basic XAML of databinding</Button>
</StackPanel>
</Window>
@@ -0,0 +1,38 @@
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 ArticleExample
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void ShowDataBindingCode_Click(object sender, RoutedEventArgs e)
{
new DataBindingCode().ShowDialog();
}
private void ShowBasicDataBinding_Click(object sender, RoutedEventArgs e)
{
new ExampleBinding().ShowDialog();
}
}
}
@@ -0,0 +1,12 @@
using System;
namespace ArticleExample
{
//<Person>
class Person
{
public string Name { get; set; }
public DateTime Birthdate { get; set; }
}
//</Person>
}
@@ -0,0 +1,9 @@
<Application x:Class="Application"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ArticleExampleVB"
StartupUri="DataBindingCode.xaml">
<Application.Resources>
</Application.Resources>
</Application>
@@ -0,0 +1,6 @@
Class Application
' Application-level events, such as Startup, Exit, and DispatcherUnhandledException
' can be handled in this file.
End Class
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net5.0-windows</TargetFramework>
<RootNamespace>ArticleExampleVB</RootNamespace>
<UseWPF>true</UseWPF>
</PropertyGroup>
<ItemGroup>
<Import Include="System.Windows" />
<Import Include="System.Windows.Controls" />
<Import Include="System.Windows.Data" />
<Import Include="System.Windows.Documents" />
<Import Include="System.Windows.Input" />
<Import Include="System.Windows.Media" />
<Import Include="System.Windows.Media.Imaging" />
<Import Include="System.Windows.Navigation" />
<Import Include="System.Windows.Shapes" />
</ItemGroup>
</Project>
@@ -0,0 +1,11 @@
Imports System.Windows
'The ThemeInfo attribute describes where any theme specific and generic resource dictionaries can be found.
'1st parameter: where theme specific resource dictionaries are located
'(used if a resource is not found in the page,
' or application resource dictionaries)
'2nd parameter: where the generic resource dictionary is located
'(used if a resource is not found in the page,
'app, and any theme specific resource dictionaries)
<Assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)>
@@ -0,0 +1,16 @@
<Window x:Class="DataBindingCode"
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:ArticleExampleVB"
mc:Ignorable="d"
Title="DataBindingCode" Height="450" Width="800"
Loaded="Window_Loaded">
<Border>
<StackPanel Width="300" Margin="35">
<Label>Person name:</Label>
<TextBlock x:Name="NameBlock" Margin="10,0,0,0" />
</StackPanel>
</Border>
</Window>
@@ -0,0 +1,46 @@
Imports System.Globalization
Public Class DataBindingCode
'<Converter>
Private Class NameConverter
Implements IValueConverter
Private Shared _instance As New NameConverter
Public Shared ReadOnly Instance As NameConverter = _instance
Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.Convert
Return $"[[ {value} ]]"
End Function
Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.ConvertBack
Return value.ToString().Trim("[", "]", " ")
End Function
End Class
'</Converter>
'<SetBinding>
Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs)
' Make a new data source object
Dim personDetails As New Person() With {
.Name = "John",
.Birthdate = Date.Parse("2001-02-03")
}
' New binding object using the path of 'Name' for whatever source object is used
Dim nameBindingObject As New Binding("Name")
' Configure the binding
nameBindingObject.Mode = BindingMode.OneWay
nameBindingObject.Source = personDetails
nameBindingObject.Converter = NameConverter.Instance
nameBindingObject.ConverterCulture = New CultureInfo("en-US")
' Set the binding to a target object. The TextBlock.Name property on the NameBlock UI element
BindingOperations.SetBinding(NameBlock, TextBlock.TextProperty, nameBindingObject)
End Sub
'</SetBinding>
End Class
@@ -0,0 +1,12 @@
<Window x:Class="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:ArticleExampleVB"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
</Grid>
</Window>
@@ -0,0 +1,3 @@
Class MainWindow
End Class
@@ -0,0 +1,8 @@
'<Person>
Public Class Person
Public Property Name As String
Public Property Birthdate As DateTime
End Class
'</Person>
+2
View File
@@ -72,6 +72,8 @@ landingContent:
links:
- text: About data binding
url: data/index.md
- text: Declare bindings
url: data/binding-declarations-overview.md
- title: XAML in WPF
linkLists:
+4
View File
@@ -51,6 +51,10 @@ items:
items:
- name: Overview
href: data/index.md
- name: Declare a binding
href: data/binding-declarations-overview.md
- name: Binding sources
href: data/binding-sources-overview.md
- name: Systems
expanded: true
items: