[WPF] chapter thirty-learning element is bound - bound to non-target elements

Original: [WPF] chapter thirty-learning element is bound - bound to non-target elements

  Previous chapters have been discussing how to add a link to bind two of the elements. But in data-driven applications, a more common scenario is to create a binding expression never visible objects extracted data. The only requirement is to display the information must be stored in the public property. WPF data binding data structure can not obtain private or public information field.

  When bound to a non-elemental objects, you need to give up Binding.ElementName property, and use one of the following attributes:

  •   The Source : This attribute is a reference to the source object - in other words, to provide a data object.
  •   RelativeSource : This is a reference, use RelateSource objects point to the source object. With reference to the underlying construct that additional layers may be the current element (the element comprising a binding expressions) on. This seems unnecessarily increases the complexity. But in fact, RelativeSource property is a special tool, when the write control templates and data templates easily.
  •   The DataContext : If you do not use the Source property to specify the source or RelativeSource, WPF began to look up the element tree from the current element. DataContext attribute checks each element, and uses the first non-null DataContext property. When I want to bind to different elements with multiple properties of an object, the DataContext property is very useful, because may be at a higher level of container objects (rather than directly on the target element) set the DataContext property.

A, Source Properties

  Source property is very simple. The only problem is to bind, you need to have a data object. Later you will see centralized method can be used to obtain the data object. Resources may be extracted from the data object, the data object may be generated by writing code, data objects may be acquired with the help of the data provided.

  The easiest option is to point to some of the Source property ready static objects. For example, you can create a static object in your code and use the object. Alternatively, the components may be used from a .NET class library. As follows:

<TextBlock Margin="5" Text="{Binding Source={x:Static SystemFonts.IconFontFamily}, Path=Source}"></TextBlock>

  This binding expression gets FontFamily objects provided by the static properties SystemFonts.IconFontFamily (Note that in order to set Binding.Source property, it needs static markup extension). Then FontFamily.Source Binding.Path property to property, to attribute gives the name of the font family. The result is a line of text. In Windows Vista or Windows 7, the font name segoe UI display.

  Another option is to bind to an object previously created as a resource. For example, the following tags to create FontFamily objects point Calibri font:

<Window.Resources>
        <FontFamily x:Key="CustomFont">Calibri</FontFamily>
</Window.Resources>

  And the following TextBlock element will be bound to that resource:

<TextBlock Margin="5" Text="{Binding Source={StaticResource CustomFont}, Path=Source}"></TextBlock>

  You will now see the text Calibri.

Two, RelativeSource property

  By RelativeSource point source object property from the relationship with respect to the target object. For example, a binding element RelativeSource property itself or to its parent element (not know how many generations between the parent element in the element tree from the current element to the parent element is bound to the binding).

  To set Binding.RelativeSource property, use RelativeSource objects, which will become more complex syntax, because the need to create a Binding object, but also will need to create nested RelativeSource object. One option is to use the property set identifier syntax instead of using the Binding extension. For example, the following code creates a Binding object TextBlock.Text property, use this time to find Binding object parent window and displays the window title RelativeSource objects:

Copy the code
<TextBlock>
    <TextBlock.Text>
                <Binding Path="Title">
                        <Binding.RelativeSource>
                                <RelativeSource Mode="Findncestor" AncestorType="{x:Type Window}" />
                        </Binding.RelativeSource>
                </Binding>
    </TextBlock.Text>
</TextBlock>
Copy the code

  RelativeSource objects using FindAncestor mode, which inform find an element tree until you find AncestorType attributes defined element type.

  More commonly prepared by binding methods using labeled RelativeSource Binding and extension, incorporate it into a string, as follows:

<TextBlock Text="{Binding Path=Title,RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Window}} }">
</TextBlock>

  When you create an object RelativeSource, FindAncestor model has 4, the following table lists all of mode 4.

Table RelativeSourceMode enumeration value

 

   RelativeSource property seem redundant, and will mark becomes complicated. After all, why not use the Source or Element property is bound directly to the source you want to use it? However, it is not always possible to use the Source or ElementName property, usually because the source and target objects in the different labeling block. When you create control templates and data templates that happens. For example, if you are building a data module to change the list of items displayed, you may need to access the top ListBox object to read the property.

Three, DataContext property

  In some cases, a large number of elements will be bound to the same object. For example, the following analysis of a set of TextBlock elements, each TextBlock elements using similar binding expression to extract the default font icons associated with different details, including line spacing, and the first font style, and weight (both are it is a simple regular expressions). Source property can be used for each TextBlock element, but this will mark becomes very long:

<TextBlock Margin="5" Text="{Binding Source={x:Static SystemFonts.IconFontFamily}, Path=LineSpacing}"></TextBlock>
<TextBlock Margin="5" Text="{Binding Source={x:Static SystemFonts.IconFontFamily}, Path=FamilyTypefaces[0].Style}"></TextBlock>
<TextBlock Margin="5" Text="{Binding Source={x:Static SystemFonts.IconFontFamily}, Path=FamilyTypefaces[0].Weight}"></TextBlock>

  In this case, a one-time use FrameworkElement.DataContext attributes define the binding source will be clearer and more flexible. In this example, set the DataContext property StackPanel panel contains all the elements of the TextBlock is reasonable (even DataContext property can also be set at a higher level - for example, the entire window - but in order to make the intent clearer as small as possible performed better within a defined range).

  Binding.Source can use and set the same property is provided a method DataContext property element. In other words, may be provided inline objects, extracted from the static properties, or extracted from the resources, as follows:

<StackPanel Margin="10" DataContext="{x:Static SystemFonts.IconFontFamily}">

  Binding expression can now be streamlined by omitting information sources:

<TextBlock Margin="5" Text="{Binding Path=Source}"></TextBlock>

  When the source information is omitted in the binding expression, WPF checks DataContext element attributes. If the attribute value is null, WPF will continue to look up a first data context is not null (initially, DataContext properties of all the elements are null) in the element tree. If you find a data context, it was found to bind the data context to use. If none is found, binding expression does not apply any value for the target property.

  

 

Guess you like

Origin www.cnblogs.com/lonelyxmas/p/12285981.html