有很多文章讨论绑定的概念,并讲解如何使用StaticResources和DynamicResources绑定属性。这些概念使用WPF提供的数据绑定表达式。在本文中,让我们研究WPF提供的不同类型的数据绑定表达式。

介绍

数据绑定是一种强大的技术,它允许数据在UI元素和业务模型之间流动。当业务模型中的数据发生变化时,它会自动将更改反映到UI元素上。

Models Description
OneWay Source → Destination
TwoWay Source ←→ Destination
OneWayToSource Source ← Destination
OneTime Source → Destination (only once)

这可以通过WPF提供的不同类型的数据绑定表达式来实现。

数据绑定表达式的类型如下所示。

  • DataContext绑定

  • RelativeSource绑定

  • 集合当前项绑定

1、DataContext绑定

DataContext是一个依赖属性,它是绑定的默认源。Datacontext沿着逻辑树继承。因此,如果您设置一个DataContext来控制逻辑树中的所有子元素,它也将引用同一个DataContext,除非并且直到显式指定了另一个源。

让我们举个例子来更详细地理解它。

1.1 创建一个类Book,如下所示。

public class Book
{  public string Name {  get;  set;  }  public string Author {  get;  set;  }
}

1.2 添加一个XAML文件DataContextBinding.XAML并放置四个TextBlock,如下所示。

<Grid VerticalAlignment="Center">  <Grid.RowDefinitions>  <RowDefinition Height="40" />  <RowDefinition Height="40" />  </Grid.RowDefinitions>  <Grid.ColumnDefinitions>  <ColumnDefinition Width="Auto" />  <ColumnDefinition Width="Auto" />  </Grid.ColumnDefinitions>  <TextBlock Text="Book Name:" FontWeight="Bold" />  <TextBlock Grid.Column="1" />  <TextBlock Text="Author:" FontWeight="Bold" Grid.Row="1" />  <TextBlock Grid.Row="1" Grid.Column="1" />
</Grid>

现在,让我们看看如何使用这个DataContext属性来显示数据。

它有两种用法,如下所示。

  • 1.使用{Binding}表达式

用于直接绑定DataContext。

创建类Book的实例,初始化其属性,并将类的Name属性分配给Window的DataContext属性。

public partial class DataContextBinding: Window
{  public DataContextBinding() {  InitializeComponent();  //Create the instance  Book book = new Book();  //initialize the properties  book.Name = "Computer Networking";  //Assign the Property as DataContext  this.DataContext = book.Name;  }
}

由于DataContext是沿着逻辑树和数据book继承的,因此Name被绑定到Control Window。Window的所有子元素也将引用同一个对象(book.Name)。

要显示数据,请将DataContext与Textblock绑定,如下所示。

<TextBlock Text="Book Name:" FontWeight="Bold"/>
<TextBlock Text="{Binding}" Grid.Column="1" />

输出

  1. 使用{Binding Property}表达式

绑定Datacontext的属性。

创建类Book的实例,初始化其属性并将类的实例(Book)分配给Window的DataContext属性。

Book book = new Book();
//initialize the properties
book.Name = "Computer Networking";
book.Author = "James F. Kurose";
//Assign the instance as DataContext
this.DataContext = book;

现在,让我们看看输出。

由于绑定表达式{Binding}用于绑定Book类型的DataContext对象,因此调用ToString()方法,并将数据显示为字符串。为了以正确的格式显示数据,我们必须将数据对象的属性与TextBlock绑定,如下所示:

<TextBlock Text="Book Name:" FontWeight="Bold"/>
<TextBlock Text="{Binding Name}" Grid.Column="1" />
<TextBlock Text="Author:" FontWeight="Bold" Grid.Row="1" />
<TextBlock Text="{Binding Author}" Grid.Row="1" Grid.Column="1"/>

绑定表达式{Binding Name}用于绑定DataContext绑定的Name属性。

输出

2、RelativeSource 绑定

RelativeSource是一个属性,它用相对关系设置绑定源以绑定目标。此扩展主要用于必须将元素的一个属性绑定到同一元素的另一个属性时。

RelativeSource有四种类型,如下所示。

  1. Self

  2. FindAncestor

  3. TemplatedParent

  4. PreviousData

让我们一个一个详细地探讨一下。

2.1 Self

Self用于绑定源和绑定目标相同的场景中。对象的一个属性与同一对象的另一个属性绑定。

例如,让我们取一个高度和宽度相同的椭圆。

在XAML文件中添加下面给出的代码。宽度属性与高度属性相对绑定。

<Grid>  <Ellipse Fill="Black" Height="100" Width="{Binding RelativeSource={RelativeSource Self},Path=Height}">  </Ellipse>
</Grid>

输出

如果改变椭圆的高度,宽度也会相对变化。

2.2 FindAncestor

顾名思义,当绑定源是绑定目标的祖先(父级)之一时使用此选项。使用FindAncestor扩展,可以找到任何级别的祖先。

让我们举个例子来更清楚地理解它。

步骤

创建XAML,它表示下面给出的元素的逻辑树。

<Grid Name="Parent_3">  <StackPanel Name="Parent_2">  <Border Name="Parent_1">  <StackPanel x:Name="Parent_0" Orientation="Vertical">  <Button></Button>  </StackPanel>  </Border>  </StackPanel>
</Grid>

现在,让我们使用FindAncestor扩展将祖先的Name属性绑定到子元素button的Content属性。

<Grid Name="Parent_3">  <StackPanel Name="Parent_2" HorizontalAlignment="Center" VerticalAlignment="Center" Width="100">  <Border Name="Parent_1">  <StackPanel x:Name="Parent_0" Orientation="Vertical">  <Button Height="50" Content="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type StackPanel},
AncestorLevel=2},Path=Name}"></Button>  </StackPanel>  </Border>  </StackPanel>
</Grid>

输出

AncestorType为“StackPanel”与AcestorLevel为“2”组合,将button的content属性与StackPanel的Name属性(Parent_2)绑定在一起。

2.3 TemplatedParent

TemplatedParent是一个属性,它使您能够创建一个包含少量未知值的控件模板。这些值取决于应用ControlTemplate的控件的属性。

让我们举个例子来更详细地理解它

步骤

  1. 为按钮创建一个ControlTemplate,如下所示。

<Window.Resources>  <ControlTemplate x:Key="template">  <Canvas>  <Ellipse Height="110" Width="155"  Fill="Black"/>  <Ellipse Height="100" Width="150"  Fill="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Background}">  </Ellipse>  <ContentPresenter Margin="35"  Content="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Content}"/>  </Canvas>  </ControlTemplate>
</Window.Resources>

在上面给出的代码中,椭圆的Fill属性和ContentPresenter的Content属性依赖于将应用此模板的控件的属性值。

  1. 添加一个按钮并对其应用模板。

<Button Margin="50" Background="Beige" Template="{StaticResource template}" Height="0" Content="Click me" FontSize="22">
</Button>

在应用模板时,按钮的Background(Beige)与椭圆的Fill属性相对绑定,Content(Click me)与ContentPresenter的Content属性相对绑定。依赖值生效并给出以下输出。

输出

2.4 PreviousData

这是相对使用最少的方式。当数据被分析时,这就出现了,我们需要表示值相对于以前数据的变化。

让我们举个例子来更详细地理解它。

步骤

  1. 创建一个类Data并实现INotifyPropertyChanged接口,如下所示

public class Data: INotifyPropertyChanged
{  public int DataValue {  get;  set;  }  public event PropertyChangedEventHandler PropertyChanged;  protected void OnPropertyChanged(string PropertyName) {  if (null != PropertyChanged) {  PropertyChanged(this,  new PropertyChangedEventArgs(PropertyName));  }  }
}
  1. 创建一个Data类型的列表并将其指定为DataContext。

public RelativeSourcePreviousData()
{  InitializeComponent();  List < Data > data = new List < Data > ();  data.Add(new Data() {  DataValue = 60  });  data.Add(new Data() {  DataValue = 100  });  data.Add(new Data() {  DataValue = 120  });  this.DataContext = data;
}
  1. 在XAML文件中添加ItemsControl。

<ItemsControl ItemsSource="{Binding}"></ItemsControl>
  1. 为其创建ItemsPanel模板,如下。

<ItemsControl ItemsSource="{Binding}">  <ItemsControl.ItemsPanel>  <ItemsPanelTemplate>  <StackPanel Orientation="Vertical" />  </ItemsPanelTemplate>  </ItemsControl.ItemsPanel>
</ItemsControl>
  1. 现在,为了正确地表示数据,创建DataTemplate,如下所示。

<ItemsControl.ItemTemplate>  <DataTemplate>  <StackPanel Orientation="Horizontal">  <Grid Margin="30,20,0,0">  <Rectangle Width="80" Height="{Binding DataValue}" Fill="Blue" />  <TextBlock Foreground="White" Margin="35,0,0,0" Text="{Binding DataValue}"></TextBlock>  </Grid>  <TextBlock Margin="30,20,0,0" Text="Previous Data:"></TextBlock>  <TextBlock VerticalAlignment="Center" Margin="5,20,0,0" Text="{Binding  RelativeSource={RelativeSource PreviousData}, Path=DataValue}" />  </StackPanel>  </DataTemplate>
</ItemsControl.ItemTemplate>

输出

蓝色框的高度是列表中项目的值,旧数据显示在右侧。该项的第一个值为“60”。因此,第一项没有旧值。

3、集合当前项绑定

在处理集合时使用。使用这个绑定表达式,您可以非常容易地读取SelectedItem的属性。斜杠是一种特殊运算符,用于处理集合中的当前项。

下面给出了三种表达式。

  1. {Binding / }

  2. {Binding Collection / }

  3. {Binding Collection / Property}

3.1 {Binding / }

此表达式用于绑定DataContext中的当前项。

让我们采取一个示例:

在下面给出的示例中,DataContext是字符串类型的国家/地区的集合,并且与Listbox绑定在一起。

步骤

  1. 创建一个Countries类并添加一个GetCountriesName()方法,该方法返回string数据类型的国家的集合,如下所示。

public class Countries
{  public static List <string> GetCountriesName() {  List <string> countries = new List <string> ();  foreach(CultureInfo culture in CultureInfo.GetCultures(CultureTypes.SpecificCultures)) {  RegionInfo country = new RegionInfo(culture.LCID);  if (!countries.Contains(country.EnglishName))  countries.Add(country.EnglishName);  }  countries.Sort();  return countries;  }
}
  1. 添加一个XAMl文件,一个ListBox和TextBlock,如下所示。

<DockPanel Name="Collection">  <ListBox ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True">  </ListBox>  <TextBlock DockPanel.Dock="Top" />
</DockPanel>
  1. 创建类Countries的实例并将Countries集合指定为DataContext。

public CurrentItemCollection()
{  InitializeComponent();  Countries countries = new Countries();  this.DataContext = countries.GetCountriesName()
}
  1. 绑定TextBlock的Text属性以将其绑定到集合的当前选定项,如下所示。

<TextBlock DockPanel.Dock="Top" Text="{Binding /}" />

输出

一旦列表项被选中,它将在右侧显示所选国家/地区。

3.2 {Binding Collection /}

此表达式用于绑定DataContext中集合属性的当前项。

例如,

DataContext是Countries类

Collection属性是CounriesList,它与ListBox绑定。

步骤

  1. 使用上面创建的类似的国家类,只是略有不同。创建返回类型为RegionInfo的方法。

public static List <RegionInfo> GetCountries()
{  List <RegionInfo> countries = new List <RegionInfo> ();  foreach(CultureInfo culture in CultureInfo.GetCultures(CultureTypes.SpecificCultures)) {  RegionInfo country = new RegionInfo(culture.LCID);  if (countries.Where(p => p.Name == country.Name).Count() == 0)  countries.Add(country);  }  return countries.OrderBy(p => p.EnglishName).ToList();
}
  1. 添加RegionInfo类型的CountriesList属性。

private List <RegionInfo> countries = null;
public List <RegionInfo> CountriesList
{  get {  if (countries == null)  countries = GetCountries();  return countries;  }
}

下面是CountriesList集合中的值的截图。

  1. 将类Countries指定为DataContext,并将Listbox与DataContext的CountriesList属性绑定。

<Window.Resources>  <vm:Countries x:Key="Countries"></vm:Countries>
</Window.Resources>
<Grid>  <DockPanel Name="Collection" DataContext="{StaticResource Countries}">  <ListBox ItemsSource="{Binding CountriesList}" IsSynchronizedWithCurrentItem="True">  <ListBox.ItemTemplate>  <DataTemplate>  <TextBlock Text="{Binding EnglishName}"></TextBlock>  </DataTemplate>  </ListBox.ItemTemplate>  </ListBox>  </DockPanel>
</Grid>
  1. 要计算CountriesList属性的当前项,请绑定TextBlock的Text属性,如下所示。

<TextBlock DockPanel.Dock="Top" Text="{Binding CountriesList/}" HorizontalAlignment="Center" FontSize="16" VerticalAlignment="Center" />

输出

右侧显示DataContext(CountriesList)中集合的当前项(CountriesList)。

3.3 {Binding Collection / Property}

此表达式用于绑定DataContext中集合的当前项的属性。

例如,如果必须计算CountriesList集合的当前项的特定属性。

在这个例子中,我想显示属性“EnglishName”的值。

为此,绑定TextBlock的Text属性,如下所示。

<TextBlock DockPanel.Dock="Top" Text="{Binding CountriesList/EnglishName}" />

输出

现在,当列表中的项被选中时,它显示属性“EnglishName”的值。

结论

我已经详细介绍了所有的数据绑定表达式。我希望这有助于您理解绑定的概念和WPF提供的表达式。


时间如流水,只能流去不流回。

  • 作者:Swati Gupta

  • 原文标题:DataBinding Expressions In WPF

  • 原文链接:https://www.c-sharpcorner.com/article/data-binding-expression-in-wpf/

  • 编辑:沙漠尽头的狼

  • 日期:2021-05-04

【翻译】WPF中的数据绑定表达式相关推荐

  1. Windows Presentation Foundation(WPF)中的数据绑定(使用XmlDataProvider作控件绑定)

    原文:Windows Presentation Foundation(WPF)中的数据绑定(使用XmlDataProvider作控件绑定) ------------------------------ ...

  2. WPF入门教程系列十五——WPF中的数据绑定(一)

    使用Windows Presentation Foundation (WPF) 可以很方便的设计出强大的用户界面,同时 WPF提供了数据绑定功能.WPF的数据绑定跟Winform与ASP.NET中的数 ...

  3. 【值转换器】 WPF中Image数据绑定Icon对象

    原文:[值转换器] WPF中Image数据绑定Icon对象 这是原来的代码: <Image Source="{Binding MenuIcon}"  /> 这里的Men ...

  4. WPF入门教程系列十六——WPF中的数据绑定(二)

    三.绑定模式 通过上一文章中的示例,学习了简单的绑定方式.在这里的示例,要学习一下绑定的模式,和模式的使用效果. 首先,我们来做一个简单示例,这个示例是根据ListBox中的选中项,去改变TextBl ...

  5. WPF中的数据绑定Data Binding使用小结

    完整的数据绑定的语法说明可以在这里查看: http://www.nbdtech.com/Free/WpfBinding.pdf MSDN资料: Data Binding: Part 1 http:// ...

  6. 数据绑定表达式(下):.NET发现之旅(二)

    这一节继续来谈.NET中的数据绑定表达式. 本节涉及的内容如下: 一,数据绑定方法的来源以及在低层上的实现. 二,数据绑定方法的执行效率排序. <%#Container.DataItem%> ...

  7. ASP.NET 3.5核心编程学习笔记(18):数据绑定表达式

    简单数据绑定 数据绑定表达式是由<%...%>包裹的可执行代码,以#号为前缀.它可以通过DataBoundLiteralControl类的实例以编程方式加以管理. 数据绑定表达式通常从数据 ...

  8. 【翻译】WPF 中附加行为的介绍 Introduction to Attached Behaviors in WPF

    [翻译]WPF 中附加行为的介绍 Introduction to Attached Behaviors in WPF 目录  隐藏 引言 [Introduction] 背景 [Background] ...

  9. WPF中的Data Binding调试指南

    点击蓝字"大白技术控"关注我哟 加个"星标★",每日良时,好文必达! WPF中的Data Binding如何Debug? 大家平时做WPF开发,相信用Visua ...

最新文章

  1. soapui工具_基于开源的API测试工具!不再为web服务负载测试而发愁
  2. 【CF】142 Div.1 B. Planes
  3. 一文看懂Python(二)-----字符串篇
  4. 不要在nodejs中阻塞event loop
  5. 禅道8.2-9.2.1注入GetShell
  6. What he did
  7. 用Cython加速Python到“起飞”
  8. 中国风海报设计模板,东方韵味尽显
  9. (转载)github简单使用教程
  10. 恒大继续押宝造车 9.3亿美元收购NEVS的51%股权
  11. npm install 报错(npm ERR! errno 1)
  12. 解决JDK13版本后IntelliJ IDEA导入新字体文件
  13. 计算机课程设计参考文献,计算机课程设计专著参考文献 计算机课程设计论文参考文献哪里找...
  14. java NIO BIO和AIO
  15. 什么是软件众包?软件众包有什么价值?
  16. numpy、pandas下载速度慢问题
  17. HDU6057 Kanade‘s convolution
  18. C++ BMI指数(身体质量指数) 计算程序
  19. 从键盘输入一个小写英文字母,将其转换为大写英文字母
  20. 蚂蚁集团SOFAStack、Tugraph等产品入选信通院软件供应链安全名录

热门文章

  1. 18秋学期《计算机网络》在线作业,18秋北交《计算机应用基础及计算机网络与应用》在线作业一-2辅导资料.docx...
  2. linux隐写文件剥离,杂项的基本解题思路(1)——文件操作隐写、图片隐写
  3. sublime text3:提示 There are no packages available installation 解决方案
  4. context:annotation-config vs context:component-scan
  5. iOS回顾笔记( 02 ) -- 由九宫格布局引发的一系列“惨案”
  6. java mina unix client
  7. Microsoft AJAX Client Library规范的实例
  8. Mac OS X必备APP推荐之二
  9. 您的MyFitnessPal帐户几乎肯定已被黑客入侵,请立即更改密码
  10. 10以内数的组成分解图_大班数学教案《10以内数的组成》