长春火车站附近美食,软件培训,一般做海报的图片跟哪个网站下载,广东广州简单的说#xff0c;数据绑定是一种关系#xff0c;该关系告诉WPF从源对象提取一些信息#xff0c;并用这些信息设置目标对象的属性。目标属性始终是依赖属性#xff0c;通常位于WPF元素中——毕竟#xff0c;WPF数据绑定的最终目标是在用户界面中显示一些信息。然而…简单的说数据绑定是一种关系该关系告诉WPF从源对象提取一些信息并用这些信息设置目标对象的属性。目标属性始终是依赖属性通常位于WPF元素中——毕竟WPF数据绑定的最终目标是在用户界面中显示一些信息。然而源对象可以是任何内容从另一个WPF元素乃至ADO.NET数据对象如DataTable、DataRow或您自行创建的纯数据对象。
将元素绑定到一起
数据绑定最简单的情形是源对象是WPF元素而且源属性是依赖项属性依赖性属性具有内置的更改通知支持。因此当在源对象中改变依赖项属性的值时会立即更新目标对象中的绑定属性这正是我们所需要的的行为——而且不必为此构建任何额外的基础结构。
Slider NamesliderFontSize Minimum1 Maximum40 Value10 TickFrequency1 /
TextBlock x:NametextBlockFontSize FontSize{Binding ElementNamesliderFontSize, PathValue, ModeTwoWay} TextSimple Text/
TextBlock NametextBlockFontSize2 TextSimple Text/
textBlockFontSize2.SetBinding(TextBlock.FontSizeProperty, new Binding(Value) { ElementName sliderFontSize, ModeBindingMode.TwoWay });
这里将两个TextBlock的FontSize属性绑定到Slider的Value属性上其中一个通过绑定表达式设置另一个则是通过代码设置现在在滑动Slider的滑块时两个TextBlock 的字体大小会随之发生变化。
数据绑定表达式使用XAML标记扩展也会创建一个Binding 类的实例所以绑定表达式以 Binding 开头。
使用代码创建绑定时先创建一个绑定对象构造函数参数指定Path字段然后设置Binding相关的属性值通过绑定目标的SetBinding函数将绑定目标的属性与Binding对象关联即可。
因为基于标记的绑定更清晰并且需要完成的工作更少所以更常用。但在一些特殊情况下会希望使用代码创建绑定
创建动态绑定 如果希望根据其他运行时信息修改绑定或者根据环境创建不同的绑定这时使用代码创建绑定通常更合理此外也可以在窗口的Resources集合中定义可能希望使用的每个绑定并只添加使用合适的绑定对象调用SetBinding() 方法的代码。
删除绑定 如果希望删除绑定从而可以通过普通方式设置属性需要借助ClearBinding() 或 ClearAllBinding() 方法。仅为属性应用新值是不够的——如果正在使用双向绑定设置的值会传播到链接的对象并且两个属性保持同步。
绑定错误
WPF不会引发异常来通知与数据绑定相关的问题。如果指定的元素或属性不存在那么不会收到任何指示只是不能在目标属性中显示数据。WPF会输出绑定失败细节的跟踪信息。当调试应用程序时该信息显示在Visual Studio 的输出窗口中。
绑定模式
绑定模式通过Binding.Mode 属性设置WOF允许使用5个枚举值中的任何一个。
OneWay当源属性变化时更新目标属性
TwoWay当源属性变化时更新目标属性并且当目标属性变化时更新源属性
OneTime最初根据源属性值设置目标属性然后其后的所有变化都会被忽略。通常如果知道源属性不会变化可使用这种模式降低开销
OneWayToSource与OneWay类似但方向相反当目标属性变化时更新源属性
Default此类绑定依赖于目标属性。既可以是双向的对于用户可以设置的属性如TextBox.Text也可以是单向的对于所有其它属性。除非明确指定了一种模式否则所有绑定都是用该方式。
使用代码检索绑定
可使用代码检索绑定并检查其属性而不必考虑绑定最初是使用代码还是标记创建的。可采用两种方式来获取绑定信息
1、使用静态方法 BindingOperations.GetBinding() 来检索相应的Binding 对象。
2、使用静态方法 BindingOperations.GetBindingExpression() 方法获得更实用的 BindingExpression对象。
Binding binding BindingOperations.GetBinding(textBlockFontSize, TextBox.FontSizeProperty);
MessageBox.Show(Bound binding.Path.Path to source element binding.ElementName);//BindingExpression expression BindingOperations.GetBindingExpression(textBlockFontSize, TextBlock.FontSizeProperty);
BindingExpression expression textBlockFontSize.GetBindingExpression(TextBlock.FontSizeProperty);
MessageBox.Show(Bound expression.ResolvedSourcePropertyName with data ((Slider)expression.ResolvedSource).Value);
多绑定
可以为一个控件设置多个绑定比如为TextBlock的FontSize、Text分别创建各自的绑定。
甚至可以为同一个控件的同一个属性绑定至多个源。乍一看这好像不可能实现毕竟当创建绑定时只能指定一个目标属性然而可使用多种方法突破这一限制。最简单的方法是更改数据绑定模式可以将Mode属性设置为TwoWay这样可以在源上设置绑定到目标的绑定表达式。
Slider NamesliderFontSize Minimum1 Maximum40 Value10 TickFrequency1 /
TextBlock x:NametextBlockFontSize FontSize{Binding ElementNamesliderFontSize, PathValue, ModeTwoWay} TextSimple Text/
TextBlock NametextBlockFontSize2 TextSimple Text/
TextBox NametxtContent Text{Binding ElementNametextBlockFontSize, PathFontSize, ModeTwoWay}/
TextBox NametxtContent2 Text{Binding ElementNamesliderFontSize, PathValue, ModeTwoWay}/
TextBlock FontSize{Binding ElementNamesliderFontSize, PathValue, ModeTwoWay} Text{Binding ElementNametxtContent, PathText}/
双向绑定具有极大的灵活性可使用它们从源向目标以及从目标向源应用改变。还可以组合应用它们来创建非常复杂的不需要编写代码的窗口。
绑定更新
当使用OneWay 或TwoWay 绑定模式时改变后的值会立即从源传播到目标。然而反向的变化传递——从目标到源——未必会立即发生。它们的行为由 Binding.UpdateSourceTrigger 属性控制
PropertyChanged: 当目标属性发生变化时立即更新源
LostFocus:当目标属性发生变化并且目标丢失焦点时更新
Explicit:除非调用BindingExpress.UpdateSource()方法否则无法更新源
Default:根据目标属性的元数据确定更新行为。大多数属性的默认行为是PropertyChanged但TextBox.Text 属性的默认行为是LostFocus
通过BindingExpress.UpdateSource()方法更新源的方式如下
BindingExpression expression txtContent2.GetBindingExpression(TextBox.TextProperty);
expression.UpdateSource();
绑定延迟
在极少数情况下需要防止数据绑定触发操作和修改源对象至少在某一时段是这样的。可使用Binding.Delay 属性等待数毫秒之后再提交更改。
绑定到非元素对象
当绑定到非元素对象时需要放弃Binding.ElementName 属性并使用一下属性中的一个
Source该属性是指向源对象的引用——换句话说是提供数据的对象
RelativeSource这是引用使用RelativeSource 对象指向源对象。有了这个附加层可在当前元素的基础上构建引用。这似乎无谓的增加了复杂程度但实际上RelativeSource 属性是一种特殊工具当编写控件模板以及数据模板时是很方便的
DataContext如果没有使用Source或RelativeSource 属性指定源WPF就从当前元素开始在元素数中向上查找检查每个元素的DataContext 属性并使用第一个非空的DataContext 属性。当我们要将同一个对象的多个属性绑定到不同的元素是DataContext属性时非常有用的因为可在更高陈词的容器对象上而不是直接在目标元素上设置DataContext 属性。
Source属性
Source属性非常简单唯一的问题是为了进行绑定需要具有数据对象。可以使用一些已经准备好的静态对象或来自.Net类库的组件也可以是绑定到先前作为资源创建的对象。
WindowWindow.Resourceslocal:InstrumentViewModel x:Keyinstrument ExchangeIDSHSE InstrumentID600000 InstrumentName浦发银行/local:InstrumentViewModel/Window.ResourcesStackPanelTextBlock Text{Binding Source{x:Static SystemFonts.IconFontFamily}, PathSource}/TextBlock Text{Binding Source{x:Static local:MainWindow.StaticString}}/TextBlock Text{Binding Source{StaticResource instrument}, PathExchangeID}//StackPanel
/Window
RelativeSource属性
通过RelativeSource属性可根据相对于目标对象的关系指向源对象。例如可使用RelativeSource属性将元素绑定到自身或其父元素。RelativeSource 对象查找有四种模式通过Mode 属性设置
Self表达式绑定到同一元素的另一个属性上
TextBlock Text{Binding RelativeSource{RelativeSource ModeSelf}, PathForeground, StringFormat{}{0}}/
FindAncestor表达式绑定到父元素。WPF将查找元素树直至发现期望的父元素。为了指定父元素还必须设置AncestorType 属性以指示希望查找的父元素的类型。此外还可以用AncestorLevel 属性略过发现的一定数量的特定元素。例如当在一棵树中查找时如果希望绑定到第三个ListBoxItem 类型的元素应当使用如下设置—— AncestorType {x:Type ListBoxItem} 并设置 AncestorLevel 3从而略过前两个ListBoxItem 元素。默认情况下AncestorLevel 属性设置为1并在找到第一个匹配的元素时停止查找
StackPanel x:NameBindingTextBlockStackPanelTextBlock Text{Binding RelativeSource{RelativeSource ModeFindAncestor, AncestorType{x:Type StackPanel}}, PathName}/
/StackPanel
PreviousData表达式绑定到数据绑定列表中的前一个数据项。在列表项中会使用这种模式
ItemsControl ItemsSource{Binding PathInstruments}ItemsControl.ItemTemplateDataTemplateStackPanel OrientationHorizontal Margin2TextBlock Text{Binding ExchangeID} /TextBlock Text{Binding PathInstrumentID, RelativeSource{RelativeSource ModePreviousData}} ForegroundRed Margin5,0,0,0//StackPanel/DataTemplate/ItemsControl.ItemTemplate
/ItemsControl
TemplateParent表达式绑定到应用模板的元素。只有当绑定位于控件模板或数据模板内部时这种模式才能工作。
Button Width64 Height64 ContentEllipse BackgroundOrangeRedButton.TemplateControlTemplate TargetTypeButtonGridEllipse Fill{Binding RelativeSource{RelativeSource ModeTemplatedParent}, PathBackground}/ContentPresenter VerticalAlignmentCenter HorizontalAlignmentCenter//Grid/ControlTemplate/Button.Template
/Button
DataContext属性
在某些情况下会将大量元素绑定到同一个对象。对于这种情况使用DataContext 属性一次性定义绑定源会更清晰也更灵活。
StackPanel DataContext{x:Static SystemFonts.IconFontFamily}TextBlock Text{Binding PathSource}/TextBlock Text{Binding PathLineSpacing}/TextBlock Text{Binding PathFamilyTypefaces[0].Style}/TextBlock Text{Binding PathFamilyTypefaces[0].Weight}/
/StackPanel
完整代码如下
MainWindow.xaml
Window x:ClassTestElementBinding.MainWindowxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlxmlns:dhttp://schemas.microsoft.com/expression/blend/2008xmlns:mchttp://schemas.openxmlformats.org/markup-compatibility/2006xmlns:localclr-namespace:TestElementBindingmc:IgnorabledTitleMainWindow Height450 Width800Window.Resourceslocal:InstrumentViewModel x:Keyinstrument ExchangeIDSHSE InstrumentID600000 InstrumentName浦发银行/local:InstrumentViewModel/Window.ResourcesStackPanelStackPanelSlider NamesliderFontSize Minimum1 Maximum40 Value10 TickFrequency1 /TextBlock x:NametextBlockFontSize FontSize{Binding ElementNamesliderFontSize, PathValue, ModeTwoWay} TextSimple Text/TextBlock NametextBlockFontSize2 TextSimple Text/TextBox NametxtContent Text{Binding ElementNametextBlockFontSize, PathFontSize, ModeTwoWay, UpdateSourceTriggerPropertyChanged, Delay500}/TextBox NametxtContent2 Text{Binding ElementNamesliderFontSize, PathValue, ModeTwoWay, UpdateSourceTriggerExplicit}/TextBlock FontSize{Binding ElementNamesliderFontSize, PathValue, ModeTwoWay} Text{Binding ElementNametxtContent, PathText}/Button ClickButton_ClickGetBinding/ButtonButton ClickUpdateSourceButton_ClickUpdateSource/Button/StackPanelStackPanelTextBlock Text{Binding Source{x:Static SystemFonts.IconFontFamily}, PathSource}/TextBlock Text{Binding Source{x:Static local:MainWindow.StaticString}}/TextBlock Text{Binding Source{StaticResource instrument}, PathExchangeID}//StackPanelStackPanel x:NameBindingTextBlockStackPanelTextBlock Text{Binding RelativeSource{RelativeSource ModeSelf}, PathForeground, StringFormat{}{0}}/TextBlock Text{Binding RelativeSource{RelativeSource ModeFindAncestor, AncestorType{x:Type StackPanel}}, PathName}/ItemsControl ItemsSource{Binding PathInstruments}ItemsControl.ItemTemplateDataTemplateStackPanel OrientationHorizontal Margin2TextBlock Text{Binding ExchangeID} /TextBlock Text{Binding PathInstrumentID, RelativeSource{RelativeSource ModePreviousData}} ForegroundRed Margin5,0,0,0//StackPanel/DataTemplate/ItemsControl.ItemTemplate/ItemsControlButton Width64 Height64 ContentEllipse BackgroundOrangeRedButton.TemplateControlTemplate TargetTypeButtonGridEllipse Fill{Binding RelativeSource{RelativeSource ModeTemplatedParent}, PathBackground}/ContentPresenter VerticalAlignmentCenter HorizontalAlignmentCenter//Grid/ControlTemplate/Button.Template/Button/StackPanelStackPanel DataContext{x:Static SystemFonts.IconFontFamily}TextBlock Text{Binding PathSource}/TextBlock Text{Binding PathLineSpacing}/TextBlock Text{Binding PathFamilyTypefaces[0].Style}/TextBlock Text{Binding PathFamilyTypefaces[0].Weight}//StackPanel/StackPanel
/WindowMainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
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 TestElementBinding;public class ViewModelBase : INotifyPropertyChanged
{public event PropertyChangedEventHandler? PropertyChanged;protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName null){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}protected virtual bool SetPropertyT(ref T member, T value, [CallerMemberName] string? propertyName null){if (EqualityComparerT.Default.Equals(member, value)){return false;}member value;OnPropertyChanged(propertyName);return true;}
}
public class InstrumentViewModel : ViewModelBase
{private string _exchangeID string.Empty;private string _instrumentID string.Empty;private string _instrumentName string.Empty;public string ExchangeID { get _exchangeID; set SetProperty(ref _exchangeID, value); }public string InstrumentID { get _instrumentID; set SetProperty(ref _instrumentID, value); }public string InstrumentName { get _instrumentName; set SetProperty(ref _instrumentName, value); }
}public partial class MainWindow : Window
{public MainWindow(){InitializeComponent();InitInstruments();BindingTextBlockStackPanel.DataContext this;textBlockFontSize2.SetBinding(TextBlock.FontSizeProperty, new Binding(Value) { ElementName sliderFontSize, Mode BindingMode.TwoWay });}public static string StaticString { get; set; } Static String;public ObservableCollectionInstrumentViewModel Instruments { get; set; } new ObservableCollectionInstrumentViewModel ();public void InitInstruments(){Instruments.Add(new InstrumentViewModel() { ExchangeID SHSE, InstrumentID 601155, InstrumentName 新城控股 });Instruments.Add(new InstrumentViewModel() { ExchangeID SHSE, InstrumentID 600036, InstrumentName 招商银行 });Instruments.Add(new InstrumentViewModel() { ExchangeID SHSE, InstrumentID 600266, InstrumentName 城建发展 });Instruments.Add(new InstrumentViewModel() { ExchangeID SHSE, InstrumentID 600837, InstrumentName 海通证券 });Instruments.Add(new InstrumentViewModel() { ExchangeID SHSE, InstrumentID 601668, InstrumentName 中国建筑 });Instruments.Add(new InstrumentViewModel() { ExchangeID SZSE, InstrumentID 000002, InstrumentName 万科A });Instruments.Add(new InstrumentViewModel() { ExchangeID SZSE, InstrumentID 000001, InstrumentName 平安银行 });Instruments.Add(new InstrumentViewModel() { ExchangeID SZSE, InstrumentID 000623, InstrumentName 吉林敖东 });Instruments.Add(new InstrumentViewModel() { ExchangeID SZSE, InstrumentID 002739, InstrumentName 万达电影 });Instruments.Add(new InstrumentViewModel() { ExchangeID SZSE, InstrumentID 300642, InstrumentName 透景生命 });}private void Button_Click(object sender, RoutedEventArgs e){Binding binding BindingOperations.GetBinding(textBlockFontSize, TextBox.FontSizeProperty);MessageBox.Show(Bound binding.Path.Path to source element binding.ElementName);//BindingExpression expression BindingOperations.GetBindingExpression(textBlockFontSize, TextBlock.FontSizeProperty);BindingExpression expression textBlockFontSize.GetBindingExpression(TextBlock.FontSizeProperty);MessageBox.Show(Bound expression.ResolvedSourcePropertyName with data ((Slider)expression.ResolvedSource).Value);}private void UpdateSourceButton_Click(object sender, RoutedEventArgs e){BindingExpression expression txtContent2.GetBindingExpression(TextBox.TextProperty);expression.UpdateSource();}
}