zoukankan      html  css  js  c++  java
  • WPF 元素绑定

    简单来说,数据绑定是一种关系,最简单的关系就是 源对象是WPF元素而且源属性是依赖项属性

     绑定表达式

    当使用数据绑定时,不必对源对象(如Slider控件)做任何改动,只需要配置源对象使其属性具有正确的值范围

    <Slider Name="SliderFontSize"
            Margin="3"
            Minimum="1"
            Maximum="40"
            Value="10"
            TickFrequency="1"
            TickPlacement="TopLeft">
    </Slider>
    <TextBlock Margin="10,38,10,-18"
               Text="Simple Text"
               Name="lblSampleText"
               FontSize="{Binding ElementName=SliderFontSize,Path=Value}">
    
    </TextBlock>

    数据绑定表达式使用XAML标记扩展,以单词Binding开头,以上的代码设置了两个属性:ElementName属性(指示源元素)和Path属性(源元素中的属性)

    之所以使用名称Path,是因为Path可能指向属性的属性(FontFamily.Source)也可能是指向属性使用的索引器(Content.Children[0])。可构建具有多层次的路径,使其指向属性的属性的属性。

    绑定错误

    WPF不会引发异常,但会出现类似于:

    绑定模式

     单击Set to Large按钮时,会运行下面的代码

    private void Button_Click(object sender, RoutedEventArgs e){
                SliderFontSize.Value = 30;
     }

    效果会通过数据绑定强制改变字体尺寸。效果与移动滑动条上的滑块一样

    而下面的代码却无法达到正常的效果,破坏了绑定,滑块无法对字体做出改变。

    private void Button_Click(object sender, RoutedEventArgs e){
                lblSampleText.FontSize = 30;
    }

    可以使用一种方式,强制在两个方向传递数值:从源到目标以及从目标到源。

    <TextBlock Margin="40"
       Text="Simple Text"
       Name="lblSampleText"
       Width="300"
       Height="100"
       FontSize="{Binding ElementName=SliderFontSize,Path=Value,Mode=TwoWay}">

    目前还不要考虑使用双向绑定。

    但设置Binding.Mode属性时,WPF有5个

    对于几种模式,如下图

    OneWayToSource

    和OneWay的区别,是绑定表达式的放置位置

    OneWayToSource模式允许通过在通常被视为绑定源的对象中放置表达式,从而翻转源和目标。

    使用这个方式常见的原因是设置非依赖项模式(绑定表达式只能用于依赖项模式),但通过这个模式可以克服这个箱子,但前提是提供数值的属性本身是依赖项属性

    Default

    WPF使用了一种不同的,默认情况下依赖于所绑定属性的模式(每一个依赖项属性都有一个元数据 FrameworkPropertyMetadata.BindsTwoWayByDefault标志,该标志指示属性是使用单项绑定还是双向绑定)

    使用代码创建绑定

    还可以使用BindingOperation类的两个静态方法移除绑定。ClearBinding()方法使用依赖项属性(该属性具有希望删除的绑定)的引用作为参数。而ClearAllBindins()方法为元素删除所有数据绑定

    在一些特殊的情况下,会希望使用代码创建绑定

    使用代码检索绑定

    可使用代码检索绑定并检查其属性,而不必考虑绑定最初是用代码还是标记创建的

    可采用两种方式来获取绑定信息。第一种方式是使用静态方法BindingOperations.GetBinding来检索相应的Binding对象。这需要提供两个参数:绑定元素以及具有绑定表达式的属性

    一旦拥有绑定对象,就可以检查其属性。绑定元素名Binding.ElementName提供了表达式的值(这里是sliderFontSize),Binding.Path提供了PropertyPath对象从绑定对象提取绑定值,Binding.Path.Path获取绑定属性的名称(这里是Value)。还有Binding.Mode属性,用于告知绑定何时更新元素。

    WPF还允许通过调用BindingOperations.GetBingingExpression方法获得更实用的BindingExpression对象。

    BindingExpression对象包括一些属性,用于复制Bingding对象提供的信息。

     多绑定

    希望目标属性受多个源的影响,比如,如果希望使用两个相等的合法绑定来设置属性(创建绑定时,只能指定一个目标属性),可使用多种方法突破这一限制。

    最简单的方法是更改数据绑定模式,Mode属性允许改变绑定方向,(双向绑定),可使用这项技术创建多个设置同一属性的绑定表达式。

    对滑动条实例的一个变体,添加一个能设置精确字体尺寸的文本框。可以使用文本框和滑块设置字体。

    尽管不能再为FontSize属性添加另外一个绑定,但可以将新控件TextBox绑定到TextBlock.FontSize属性

    <TextBox HorizontalAlignment="Left"
                     Height="23"
                     Margin="240,304,0,0"
                     TextWrapping="Wrap"
                     Text="{Binding ElementName=lblSampleText,Path=FontSize,Mode=TwoWay}"
                     VerticalAlignment="Top"
                     Width="120" />

    Slider.Value属性是双精度类型,将TickFrequency属性设置为1,将IsSnapToTick属性设置为true

    直到文本框失去焦点,才会应用文本框中的改变。如果不希望这么做,可以使用Bindind对象的UpdateSourceTrigger属性立即更新

    注意,如果使用textbox去绑定滑块,则是立即更新

    <Window x:Class="WpfApp1.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"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <Grid>
            <Slider Name="SliderFontSize"
                    Margin="3"
                    Minimum="1"
                    Maximum="40"
                    Value="{Binding ElementName=txt,Path=Text}"
                    TickFrequency="1"
                    TickPlacement="TopLeft">
            </Slider>
            <TextBlock Margin="40"
                       Text="Simple Text"
                       Name="lblSampleText"
                       Width="300"
                       Height="100"
                       FontSize="{Binding ElementName=SliderFontSize,Path=Value,Mode=TwoWay}">
    
            </TextBlock>
            <Button Content="Set to Large"
                    HorizontalAlignment="Left"
                    Margin="608,279,0,0"
                    VerticalAlignment="Top"
                    Width="75" 
                    Click="Button_Click"/>
            <TextBox HorizontalAlignment="Left"
                     Height="23"
                     Margin="240,304,0,0"
                     TextWrapping="Wrap"
                     Text="10"
                     VerticalAlignment="Top"
                     Width="120" 
                     x:Name="txt"/>
        </Grid>
    </Window>

    绑定更新

    为什么以上两种绑定更新的时间不同?

    当使用OneWay或TwoWay绑定时,改变后的值会立即从源传播到目标。当反向传递时,从目标到源,未必会立即发送。

    它们的行为Binding.UpdateSourceTrigger属性控制,

    <TextBox HorizontalAlignment="Left"
                     Height="23"
                     Margin="240,304,0,0"
                     TextWrapping="Wrap"
                     Text="{Binding ElementName=lblSampleText,Path=FontSize,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                     VerticalAlignment="Top"
                     Width="120" />

    要完全控制对象的更新时机,可选择Explicit模式,此时由你的代码手动更新。

    可添加Apply按钮,调用BindingExpression.UpdateSouce方法,触发立即刷新行为

    当然在使用BindingExpression之前,我们需要一个类来获取。

    BindingExpression对象包括:

    为了获取BindingExpression对象,需要使用GetBindingExpression方法,并传入具有绑定的目标属性

    绑定延迟

    可以使用Binding对象的Delay属性

    绑定到非元素对象

    当绑定到非元素对象时,需要放弃Binding.ElementName属性,并使用以下属性中的一个:

     Source属性

    source为了数据绑定,需要具有数据对象。

    可使用几种方法获取数据对象。可从资源中提取数据对象,可通过编写代码生成数据对象,也可在数据提供的程序的帮助下获取数据对象。

    这个绑定表达式获取由静态属性SystemFonts.IconFontFamily提供的FontFamily对象,然后将Binding.Path属性设置为FontFamily.Source属性。

    RelativeSource

    通过RelativeSource属性可根据相对于目标对象的关系指向源对象。可使用RelativeSource属性将元素绑定到自身或父元素

    为设置Bind.RelativeSource属性,需要使用RelativeSource对象,这样需要多创建一个RelativeSource对象。

    <TextBlock>
        <TextBlock.Text>
            <Binding Path="Title">
                <Binding.RelativeSource>
                    <RelativeSource Mode="FindAncestor"
                                    AncestorType="{x:Type Window}">
                    </RelativeSource>
                 </Binding.RelativeSource>
            </Binding>
        </TextBlock.Text>
    </TextBlock>
    FindAncestor模式。告知查找元素树知道发现AncestorType属性定义的元素模式

     更常用的方法是使用Binding和RelativeSource标记扩展

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

    并不总是可以使用Source或ElementNmae,因为源对象和目标对象在不同的标记块中。

    DataContext属性

    在某些情况下,会将大量的元素绑定到同一个对象。

    可以在StackPanel里面设置绑定

    当绑定表达式中省略信息时,WPF会检查元素的DataContext属性。如果属性为null,WPF会继续向上查找不为null的数据上下文。如果找到了一个数据上下文,就为绑定使用找到的数据上下文,没有找到就不设置。

  • 相关阅读:
    4、10种数组去重的方法
    3.实现一个函数clone 可以对Javascript中的五种主要数据类型(Number、string、Object、Array、Boolean)进行复制
    2.怎么添加、移除、复制、创建、和查找节点
    1.简述同步和异步的区别
    89. 一行或多行文本超出隐藏
    88.阐述一下CSS Sprites(雪碧图)
    87、CSS属性overflow属性定义溢出元素内容区的内容会如何处理
    86.style标签写在body后与body前有什么区别?
    正则表达式:获取运算符之间变量
    反射问题(欢迎交流)
  • 原文地址:https://www.cnblogs.com/yinghualuowu/p/9504874.html
Copyright © 2011-2022 走看看