2020/11/17
前言
提示:元素绑定一些基础知识介绍
一、元素绑定
简单的说,数据绑定是一种关系,该关系告诉WPF从一个源对象提取一些信息,并使用这些信息设置目标对象的属性。目标属性总是以来属性,并且通常位于WPF元素中,毕竟,WPF数据绑定的最终目的是在用户界面中显示一些信息。然而,源对象可以是任何内容,从另一个WPF元素到ADO.NET数据对象(如DataTable和DataRow对象)或自己创建的纯数据对象。
1.元素绑定表达式
代码如下(示例):
<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:元素绑定"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Slider Name="SliderFontSize" Margin="3" Minimum="1" Maximum="40" Value="10" TickFrequency="1" TickPlacement="TopLeft"/>
<TextBlock Margin="10,38,10,-18" Text="Simple Text" Name="lblSampleText" FontSize="{Binding ElementName=SliderFontSize, Path=Value}"></TextBlock>
</Grid>
</Window>
我们可以通过上面实例看出字体可以跟着滚动条的值变大或变小,这里就很明确的出现了,两个元素捆绑在一起的现象。
数据绑定表达式使用XAML标记扩展,以单词Binding开头,以上的代码设置了两个属性:ElementName属性(指示源元素)和Path属性(源元素中的属性)
之所以使用名称Path,是因为Path可能指向属性的属性(FontFamily.Source)也可能是指向属性使用的索引器(Content.Children[0])。可构建具有多层次的路径,使其指向属性的属性的属性。
2.绑定模式
首先我们来看看一个列子
代码如下(示例):
<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:元素绑定"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<StackPanel>
<Slider Name="SliderFontSize" Margin="3" Minimum="1" Maximum="40" Value="10" TickFrequency="1" TickPlacement="TopLeft"/>
<TextBlock Height="200" Text="Simple Text" Name="lblSampleText" FontSize="{Binding ElementName=SliderFontSize, Path=Value}"></TextBlock>
</StackPanel>
<Button HorizontalAlignment="Left" Grid.Row="1" Height="50" Width="100" Content="Click Me yuan" Click="Button_Click"></Button>
<Button Content="Click Me dui" Height="50" Width="100" HorizontalAlignment="Right" Margin="0,55,0,0" Grid.Row="1" VerticalAlignment="Top" Click="Button_Click_1" />
</Grid>
</Window>
后台cs代码
代码如下(示例):
private void Button_Click(object sender, RoutedEventArgs e)
{
this.SliderFontSize.Value = 30;
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
this.lblSampleText.FontSize = 30;
}
我们发现点击第二个按钮时,目标对象发生了改变,而源对象并没有发生改变,这个就称为单向绑定,如果需要双向绑定,即目标对象改变,源对象也要改变,源对象改变,目标对象也要改变,这里就牵扯到了绑定模式
下面我们来看看常见的一些绑定模式和他的一些解释
OneWay: 当源属性变化时更新目标属性。
TwoWay: 当源属性变化时更新目标属性,并且当目标属性变化时更新源属性。
OneTime: 最初根据源属性设置目标属性,然而,其后的所有改变都会被忽略。通常如果知道属性不会变化,可通过这种模式降低开销。
OneWayToSource: 与OneWay相反,当目标属性变化时更新源属性。
Default: 此类绑定依赖于目标属性,既可以是双向的,也可以是单向的。除非明确指定了一种绑定模式,否则所有绑定使用该方法
3.使用代码进行绑定
我们在上面的Demo基础上,我们不用xaml进行绑定,我们在窗体加载事件中进行一个绑定的加载
代码如下(示例):
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Binding binding = new Binding();
binding.Source = SliderFontSize;//源对象
binding.Path = new PropertyPath("Value");//绑定的源对象的属性
binding.Mode = BindingMode.TwoWay;//绑定模式
lblSampleText.SetBinding(TextBlock.FontSizeProperty, binding);
}
还可以使用BindingOperation类的两个静态方法移除绑定。ClearBinding()方法使用依赖项属性(该属性具有希望删除的绑定)的引用作为参数。而ClearAllBindins()方法为元素删除所有数据绑定
4.多绑定
代码如下(示例):
<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:元素绑定"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<StackPanel>
<Slider Name="SliderFontSize" Margin="3" Minimum="1" Maximum="40" Value="10" TickFrequency="1" TickPlacement="TopLeft" ValueChanged="SliderFontSize_ValueChanged"/>
<TextBlock Height="100" Text="Simple Text" Name="lblSampleText" ></TextBlock>
<DockPanel>
<Label Content="Exact Size"></Label>
<TextBox Text="{Binding ElementName=lblSampleText,Path=FontSize,Mode=TwoWay}" VerticalAlignment="Center" Height="23" ></TextBox>
</DockPanel>
</StackPanel>
<Button HorizontalAlignment="Left" Grid.Row="1" Height="50" Width="100" Content="Click Me yuan" Click="Button_Click"></Button>
<Button Content="Click Me dui" Height="50" Width="100" HorizontalAlignment="Right" Margin="0,55,0,0" Grid.Row="1" VerticalAlignment="Top" Click="Button_Click_1" />
</Grid>
</Window>
上述xaml代码中Slider作为源对象,而TextBox,与TextBlock是目标对象,在这里就形成了一个一个源对象绑定了两个目标对象,自然的就形成了多绑定。
5.绑定更新
源的变化会立即影响目标,然而反向的传递从目标到源未必会立即发生。他们的行为由Binding.UpdateSourceTrigger属性控制。下面我们来了解关于这个属性的值;
代码如下(示例):
<TextBox Text="{Binding ElementName=lblSampleText,Path=FontSize,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Center" Height="23" ></TextBox>
名称
PropertyChanged: 当目标属性变化时立即更新源。
LostFocus: 当目标属性变化并且目标属性失去焦点时跟新源。
Explicit : 除非调用BindingExpression.UpdateSource()方法,否则无法更新源。
Default : 根据目标属性的元素确定更新行为。大多数属性的默认行为是PropertyChanged,但TextBox.Text属性的默认行为是LostFocus
6.绑定延迟
绑定延迟中使用的是Delay属性,主要是目标对象改变源对象的时候,会有延迟
2.绑定到非元素对象
WPF数据绑定基础结构不能获取私有信息或公有字段,必须是公有属性中。
绑定到非元素对象时,需要放弃Binding.ElementName属性,并使用以下属性之一。
Source:该属性是指向源对象的引用,提供数据的对象。
RelativeSource:这是引用,使用RelativeSource对象指向源对象。有了这个附加层,在在当前元素的基础上构建引用。这似乎增加了复杂程度,
但实际上RelativeSource属性是一种特殊工具,当编写控件模版及数据模版时是很方便的。
DataContext:如果没有使用Source或RelativeSource属性指定源,WPF就从当前元素开始在元素树中向上查找。检查每个属性的DataContext属性,并使用第一个飞空的DataContext属性。
当将同一个对象的多个属性绑定到不同的元素时,DataContext属性是非常有用的,因为可在更高层次的容器对象上,设置DataContext属性。
1.Source对象
source为了数据绑定,需要具有数据对象。
可使用几种方法获取数据对象。可从资源中提取数据对象,可通过编写代码生成数据对象,也可在数据提供的程序的帮助下获取数据对象
a.绑定到静态对象
代码如下(示例):
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily},Path=Source}"></TextBlock>
b.绑定到资源对象
代码如下(示例):
<Window.Resources>
<FontFamily x:Key="CoustomFont">Calibri</FontFamily>
</Window.Resources>![在这里插入图片描述](https://img-blog.csdnimg.cn/20201118091202507.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpYW5neHVlMzMzMw==,size_16,color_FFFFFF,t_70#pic_center)
<Grid>
<TextBlock Text="{Binding Source={StaticResource CoustomFont},Path=Source}"></TextBlock>
</Grid>
2.RelativeSource
a.通过RelativeSource属性可根据相对于目标对象的关系指向源对象。可使用RelativeSource属性将元素绑定到自身或父元素
b. 更常用的方法是使用Binding和RelativeSource标记扩展
代码如下(示例):
<TextBlock Text="{Binding Path=Title,RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Window}}}"></TextBlock>
上述代码运行的结果就是相当于把Window的title属性赋值给了TextBlock的title属性
- DataContext属性
如果同时有大量的元素绑定到同一对象上面,那这个时候DataContext属性就发挥作用了。
下面代码参考:
代码如下(示例):
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily},Path=Source}"></TextBlock>
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily},Path=Source}"></TextBlock>
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily},Path=Source}"></TextBlock>
<StackPanel DataContext="x:Static SystemFonts.IconFontFamily">
<TextBlock Text="{Binding Path=Source}"></TextBlock>
<TextBlock Text="{Binding Path=Source}"></TextBlock>
<TextBlock Text="{Binding Path=Source}"></TextBlock>
</StackPanel>
在以上的代码中,我们发现可以通过DataContext属性绑定到他上一级元素。
总结
提示: