WPF个人文档(五)—— 绑定
[!IMPORTANT]
在开始之前,我觉得我们非常有必要要先了解一下ViewModel
-
ViewModel:专门给界面(View)使用的数据对象
-
# ViewModel = 专门给界面(View)使用的数据对象
如果只讲绑定,可以简单理解为数据源对象
在这里先留一个简单的印象,后面会详细讲解,在看完本篇随笔之后,你也会对这个东西有一个较为深刻的印象
# 常用于MVVM架构(此架构我们以后再详细讲解)
Model → ViewModel → View
数据 UI数据 界面
[!NOTE]
一.元素绑定
-
[!NOTE]
WPF —— 绑定
这里,我们来看看官方对于绑定的解释
- WPF 元素绑定:将UI元素属性与数据源对象建立连接的机制,能在数据变化时自动更新界面,或在界面修改时同步数据源
- 它支持
.NET 对象、XML、集合 等多种数据源,并可通过 Binding 对象灵活配置
- 🌱
Binding = 在 UI 属性 和 数据源 之间建立连接
示例:将按钮背景色绑定到数据对象的属性
- 此处
Background 是绑定目标属性,ColorName 是绑定源属性,通过 Path 指定
<DockPanel
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:SDKSample">
<DockPanel.Resources>
<c:MyData x:Key="myDataSource" ColorName="Red"/>
</DockPanel.Resources>
<Button Background="{Binding Source={StaticResource myDataSource}, Path=ColorName}"
Width="150" Height="30">
我会变成红色!
</Button>
</DockPanel>
绑定的核心要素
- 目标对象与属性:必须是依赖属性(DependencyProperty)
- 源对象与路径:可为对象、集合、XML等,通过
Path 或 XPath 指定
- 数据上下文(DataContext):未显式指定源时,从父元素继承
- 模式(Mode):
OneWay:源 → 目标
TwoWay:双向同步
OneWayToSource:目标 → 源
OneTime:初始化一次
- 触发器(UpdateSourceTrigger):如
PropertyChanged、LostFocus 控制何时更新源
集合绑定与视图
<ListBox ItemsSource="{Binding MyItems}" />
- 若需排序、筛选、分组,可用
CollectionViewSource:
<CollectionViewSource x:Key="view" Source="{Binding MyItems}" />
<ListBox ItemsSource="{Binding Source={StaticResource view}}" />
数据转换与验证
- 类型不匹配时可实现
IValueConverter 转换值
- 可通过
ValidationRule 添加验证逻辑,并结合 ErrorTemplate 提供视觉反馈
注意事项
- 源对象应实现
INotifyPropertyChanged,集合应实现 INotifyCollectionChanged 以支持动态更新
- 合理选择绑定模式和触发器可优化性能与交互体验
这样,WPF 数据绑定不仅能减少手动更新 UI 的代码量,还能保持业务逻辑与界面的清晰分离
-
元素绑定:让一个 UI 控件的属性直接依赖另一个 UI 控件的属性,即:一个 UI 控件属性绑定到另一个 UI 控件属性
- 元素指UI控件,数据源也是控件属性
- 非常很多博主在他们的教程中都说的是,绑定就是控件绑定什么什么数据源,实际上他们说的控件是值控件属性
-
<!-- 绑定语法:{Binding ElementName=源控件名, Path=源属性, Mode=绑定模式} -->
[!CAUTION]
当你手动给一个绑定属性赋值时,WPF 会把这个 Binding 直接移除
这里用一个实例代码演示一下,如果你无法看明白,可以当作元素绑定的一个引题,在看完绑定模式后,会看明白的
-
MainWindow.xaml
-
<Window x:Class="Binding.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:Binding"
mc:Ignorable="d"
SizeToContent="Height"
Title="MainWindow" Height="470" Width="800">
<Grid>
<!-- slider(源属性) 绑定到 img(目标属性) -->
<StackPanel>
<Image x:Name="img" Source="/Images/1.png"
Opacity="{Binding ElementName=slider, Path=Value, Mode=OneWay}"/>
<TextBox HorizontalAlignment="Center" Text="{Binding ElementName=slider, Path=Value, Mode=Default}"/>
<Slider x:Name="slider" Minimum="0" Maximum="1" Value="0.5"/>
<Button Content="滑块value变变变" Margin="0, 3" Height="20" Width="120"
Click="Button_Click"/>
<Button Content="图片Opacity变变变" Margin="0, 3" Height="20" Width="120"
Click="Button_Click_1"/>
</StackPanel>
</Grid>
</Window>
-
MainWindow.xaml.cs
-
using System.Text;
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 Binding
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
slider.Value = 0.2;
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
img.Opacity = 0.8;
}
}
}
二.绑定模式
在此之前,问一个问题,你觉得绑定是必须双向的吗,还是默认双向的?
答案都不是,你以为是搞嵌入式TX,RX,RS485数据可以双向传输吗,拜托,这是上位机
WPF 绑定不是必须双向,而且默认也不是双向
大多数绑定其实是 单向(OneWay)默认绑定模式其实是“控件决定的”
默认模式不是 Binding 决定的,而是由 控件属性的 DependencyProperty 决定的
1.🌱OneWay — 单向绑定
-
数据流向:数据 只从数据源流向 UI
-
适用场景:显示数据,状态显示,只读 UI
2.🌱TwoWay — 双向绑定
-
数据流向:数据 双向同步(数据源 ⇿ UI)
-
适用场景:输入框,表单,参数设置
3.🌱OneWayToSource — 单向反向绑定
4.🌱OneTime — 仅进行一次的绑定
-
数据绑定:只在初始化进行一次绑定
-
适用场景:版本号,初始化数据,静态信息
5.🌱Default — 自动档
-
本质:延迟决定绑定模式,它实际上是一个占位符
-
当没有显式指定 Mode 时,Binding 的默认值就是 Default
-
# 你写的代码
<TextBox Text="{Binding UserName}" />
# 实际上等价于
<TextBox Text="{Binding UserName, Mode=Default}" />
-
工作方式
6.示例代码
-
MainWindow.xaml
-
<Window x:Class="Binding.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:Binding"
mc:Ignorable="d"
SizeToContent="Height"
Title="MainWindow" Height="470" Width="800">
<Grid>
<!-- slider(源属性) 绑定到 img(目标属性) -->
<StackPanel>
<!-- 🚩你可以修改这里的Mode枚举值来尝试上面讲述的5种数据模式 -->
<!-- 绑定语法:{Binding ElementName=源控件名, Path=源属性, Mode=绑定模式} -->
<Image x:Name="img" Source="/Images/1.png"
Opacity="{Binding ElementName=slider, Path=Value, Mode=TwoWay}"/>
<TextBox HorizontalAlignment="Center" Text="{Binding ElementName=slider, Path=Value, Mode=Default}"/>
<Slider x:Name="slider" Minimum="0" Maximum="1" Value="0.5"/>
<Button Content="滑块value变变变" Margin="0, 3" Height="20" Width="120"
Click="Button_Click"/>
<Button Content="图片Opacity变变变" Margin="0, 3" Height="20" Width="120"
Click="Button_Click_1"/>
</StackPanel>
</Grid>
</Window>
-
MainWindow.xaml.cs
-
using System.Text;
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 Binding
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
slider.Value = 0.2;
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
img.Opacity = 0.8;
}
}
}
[!WARNING]
当我们以上面的代码使用OneWay模式时,会出现一种特殊的情况:绑定失效
这是单向绑定,当我们使用第一个按钮时,数据是正常单向传递的
但是当我们使用第二个按钮时,数据反向传输后,使用其他控件,会发现:没有任何变化,绑定生效了
为什么会出现这种情况呢?
-
因为:当你手动给一个绑定属性赋值时,WPF 会把这个 Binding 直接移除
-
这里涉及到一个优先级的问题,也就是WPF 会把这个 Binding 直接移除的原因
- 第一个按钮:
slider.Value 改变 → img.Opacity 自动变化
- 第二个按钮:
img.Opacity = 0.8;
-
WPF 的依赖属性系统会执行一个优先级规则
-
而这句代码:
// 设置的是 Local Value(本地值)
// 本地值的优先级高于 Binding
img.Opacity = 0.8;
// 于是 WPF 做了一个很干脆的动作
// 移除 Binding
// 保留 Local Value
随笔参考:
1.WPF数据绑定深度解析:告别冗余事件,掌握5种绑定模式的精髓 - blfbuaa - 博客园
2.59.第8章_绑定模式_哔哩哔哩_bilibili
三.高级数据绑定:多绑定、绑定更新、延迟绑定
-
很多开发文档将多绑定,绑定更新,延迟绑定统称为高级数据绑定(Advanced Data Binding),
或者绑定行为控制(Binding Behavior Control),但是不管怎么说,他们都是在做三件事情
-
数据从哪里来?什么时候更新?如何组合?
-
| 功能 |
控制内容 |
多绑定MultiBinding |
控制 数据来源数量 |
绑定更新UpdateSourceTrigger |
控制 更新时机 |
延迟绑定Delay |
控制 更新节奏 |
-
高级绑定特性
├─ 多源绑定
│ └─ MultiBinding
│
├─ 绑定更新控制
│ └─ UpdateSourceTrigger
│
└─ 更新节流控制
└─ Delay
======================================================================
# 这只小狐狸🦊永远忘不了他的树状图了
======================================================================
# 逻辑框架理解
# WPF 的 Binding 系统其实像一条 数据管道系统
# 不同机制负责不同控制点:
数据源
↓
Binding
↓
[ 🌱多绑定 MultiBinding ] ← # 控制数据来源数量
↓
Converter
↓
UI
↓
[ 🌱UpdateSourceTrigger ] ← # 控制更新时机
↓
[ 🌱Delay ] ← # 控制更新节奏
↓
ViewModel
1.🌱多绑定(MultiBinding)
随笔参考:
1.DataBinding:绑定多属性MultiBinding、IMultiValueConverter - 知乎
2.60.第8章_多绑定_绑定更新_绑定延迟_哔哩哔哩_bilibili
3.数据绑定概述 - WPF | Microsoft Learn
2.🌱绑定更新(UpdateSourceTrigger)
(1)PropertyChanged —— 实时更新
(2)LostFocus (TextBox 默认) —— 失去焦点才更新
(3)Explicit —— 手动更新
(4)Default —— 自动档
3.🌱延迟绑定 (Delay)
四.非元素对象绑定
在此之前,我们来重新认识一下Binging.elementName属性(元素名称)
-
Binging.elementName属性
- elementName,翻译一下就是:元素名称
- 它的设计目标就是——绑定到“界面元素”
- 如果数据源不是 UI 元素,这个属性基本就该退场了
-
# 再来回顾一下,元素绑定绑定语法:
{Binding ElementName=源控件名, Path=源属性, Mode=绑定模式}
# 示例
<TextBlock Text="{Binding ElementName=slider, Path=Value}" />
<Slider x:Name="slider" />
Slider.Value
↓
TextBlock.Text
这一小节,我们来讲解非元素绑定的三种方式,当然,你也可以根据你的理解
根据不同的分类方式分类,
- 根据绑定的对象类型,可以分为 :
- 1.
DataContext对象(最常用,数据上下文对象)
- s2.静态对象
- 3.资源对象(
Resource)
- 根据绑定的数据源获取途径(入口),分为:
- 1.
Source(显式数据源)
- 2.
RelativeSource(相对对象)
- 3.
DataContext(默认数据源)
在本小节中,我们会根据数据源获取途径继续讲解
因为刚好有现成的Demo可以白嫖.......
1.🌱Source(显式数据源 —— 直接指定)
(1)静态绑定 & 静态资源绑定
-
<Window x:Class="Non_element_binding.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:Non_element_binding"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<FontFamily x:Key="my_font">
微软雅黑
</FontFamily>
</Window.Resources>
<Grid>
<StackPanel>
<!-- 1.静态绑定 - 将系统默认字体格式绑定到TextBlock-Text -->
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily}, Path=Source}"
Margin="50" HorizontalAlignment="Center"/>
<!-- 2.绑定到资源对象 -->
<TextBlock Text="{Binding Source={StaticResource my_font}, Path=Source}"
Margin="10" HorizontalAlignment="Center"/>
</StackPanel>
</Grid>
</Window>
(2)普通对象
-
User.cs
我们添加一个额外的类,仅做演示
-
MainWindow.xaml
-
<Window x:Class="Non_element_binding.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:Non_element_binding"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<!-- 3.普通对象(最常见) -->
<local:User x:Key="my_user" Name="史蒂夫"/>
</Window.Resources>
<Grid>
<StackPanel>
<!-- 3.普通对象(最常见) -->
<TextBlock Text="{Binding Source={StaticResource my_user}, Path=Name}"
Margin="10" HorizontalAlignment="Center"/>
</StackPanel>
</Grid>
</Window>
(3)ObjectDataProvider(据说是一种老派 WPF 技术)
(4)x:Reference标记扩展
-
[!IMPORTANT]
x:Reference
x:Reference 这个东西其实是 XAML 世界里的“指针”
- 作用:拿到某个已经存在的对象实例,然后当作 绑定的资源
- 和常见的
ElementName 很像,但机制不一样
x:Reference 属于 XAML 标记扩展,来自XAML体系
-
x:Reference → 找到某个对象实例
Binding → 从这个实例读取属性
# 数据流
对象实例
↓
Binding
↓
目标属性
-
这里我们使用一个滑块,让 TextBlock 实时显示它的值
-
<Window x:Class="Non_element_binding.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:Non_element_binding"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<StackPanel>
<!-- 5.标记扩展 -->
<Slider x:Name="slider" Value="50"
Minimum="0" Maximum="100"/>
<TextBlock Text="{Binding Source={x:Reference slider}, Path=Value}"
FontSize="30" HorizontalAlignment="Center"/>
</StackPanel>
</Grid>
</Window>
-
[!IMPORTANT]
ElementName 和x:Reference的区别
(5)整体代码
-
// User.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Non_element_binding
{
public class User
{
public string Name { get; set; } = string.Empty;
}
}
-
<Window x:Class="Non_element_binding.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:Non_element_binding"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<!-- 2.静态资源字典对象 -->
<FontFamily x:Key="my_font">
微软雅黑
</FontFamily>
<!-- 3.普通对象(最常见) -->
<local:User x:Key="my_user" Name="史蒂夫"/>
<!-- 4.ObjectDataProvider -->
<ObjectDataProvider x:Key="now"
ObjectType="{x:Type sys:DateTime}"
MethodName="get_Now"/>
</Window.Resources>
<Grid>
<StackPanel>
<!-- 1.静态绑定 - 将系统默认字体格式绑定到TextBlock-Text -->
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily}, Path=Source}"
Margin="50" HorizontalAlignment="Center"/>
<!-- 2.绑定到资源字典对象 -->
<TextBlock Text="{Binding Source={StaticResource my_font}, Path=Source}"
Margin="10" HorizontalAlignment="Center"/>
<!-- 3.普通对象(最常见) -->
<TextBlock Text="{Binding Source={StaticResource my_user}, Path=Name}"
Margin="10" HorizontalAlignment="Center"/>
<!-- 4.ObjectDataProvider -->
<TextBlock FontSize="30" Margin="10"
HorizontalAlignment="Center"
Text="{Binding Source={StaticResource now}}"/>
<!-- 5.标记扩展 -->
<Slider x:Name="slider" Value="50"
Minimum="0" Maximum="100"/>
<TextBlock Text="{Binding Source={x:Reference slider}, Path=Value}"
FontSize="30" HorizontalAlignment="Center"/>
</StackPanel>
</Grid>
</Window>
2.🌱RelativeSource(相对资源 —— 从视觉树查找资源)
-
我们先来翻译一下这个单词
Relative = 相对的,Source = 数据源
- 所以直接翻译就是相对资源
-
换句话说:数据源不是外部对象,而是“和当前控件有关系的对象”
-
RelativeSource 有四种模式,即:枚举体RelativeSourceMode有4种数值
Self
FindAncestor
TemplatedParent
PreviousData
(1)Self — 绑定自己
-
# 这两个绑一起了,然后永远都是一个正方形了,永远.....永远.....(海绵宝宝口音)
TextBox.Width
↓
TextBox.Height
-
<TextBlock Height="50" Width="{Binding RelativeSource={RelativeSource Self}, Path=Height}"/>
(2)FindAncestor — 寻找先祖控件
(3)TemplatedParent — 模板父控件(绑定到应用模板的元素)
(4)PreviousData — 绑定到数据绑定列表中(集合)的前一个数据项(很少使用)
3.DataContext(数据上下文)
-
在讲解数据上下文之前,我们先给出一个示例,来解释这个东西到底是个啥
-
<Grid>
<StackPanel>
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily}, Path=Source}"/>
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily}, Path=LineSpacing}"/>
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily}, Path=FamilyTypefaces[0].Style}"/>
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily}, Path=FamilyTypefaces[0].Weight}"/>
</StackPanel>
</Grid>
-
但是我们这样写非常麻烦,每次都要写绑定这个Source={x:Static SystemFonts.IconFontFamily}
-
于是,我们就可以使用数据上下文(在上一级控件上声明数据上下文)减少代码量
-
<Grid>
<StackPanel DataContext="{x:Static SystemFonts.IconFontFamily}">
<TextBlock Text="{Binding Path=Source}"/>
<TextBlock Text="{Binding Path=LineSpacing}"/>
<TextBlock Text="{Binding Path=FamilyTypefaces[0].Style}"/>
<TextBlock Text="{Binding Path=FamilyTypefaces[0].Weight}"/>
</StackPanel>
</Grid>
<!-- 当然,你还可以更加简洁 -->
<Grid>
<StackPanel DataContext="{x:Static SystemFonts.IconFontFamily}">
<TextBlock Text="{Binding Source}"/>
<TextBlock Text="{Binding LineSpacing}"/>
<TextBlock Text="{Binding FamilyTypefaces[0].Style}"/>
<TextBlock Text="{Binding FamilyTypefaces[0].Weight}"/>
</StackPanel>
</Grid>
<!-- 当然的当然,你还可以在父控件的父控件上使用数据上下文 -->
<Grid DataContext="{x:Static SystemFonts.IconFontFamily}">
<StackPanel>
<TextBlock Text="{Binding Source}"/>
<TextBlock Text="{Binding LineSpacing}"/>
<TextBlock Text="{Binding FamilyTypefaces[0].Style}"/>
<TextBlock Text="{Binding FamilyTypefaces[0].Weight}"/>
</StackPanel>
</Grid>
<!-- 当然的当然的当然(你还有完没完),只要是上层控件都可以使用,但是层级越高,性能消耗越高 -->
<Window x:Class="DataContext.MainWindow"
DataContext="{x:Static SystemFonts.IconFontFamily}"
......
<Grid>
<StackPanel>
<TextBlock Text="{Binding Source}"/>
<TextBlock Text="{Binding LineSpacing}"/>
<TextBlock Text="{Binding FamilyTypefaces[0].Style}"/>
<TextBlock Text="{Binding FamilyTypefaces[0].Weight}"/>
</StackPanel>
</Grid>
</Window>
-
所以此时此刻,我们可以得出结论
-
当然 有完没完啊你
-
我们不仅可以在xaml代码中声明数据上下文,也可以在C#代码中声明数据上下文
-
MainWindow.xaml.cs
-
using System.Text;
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 DataContext
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new User { Name = "无名氏", Age = 100 };
}
}
public class User
{
public string Name { get; set; } = string.Empty;
public int Age { get; set; }
}
}
-
MainWindow.xaml
-
<Window x:Class="DataContext.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:DataContext"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<StackPanel>
<StackPanel DataContext="{x:Static SystemFonts.IconFontFamily}">
<TextBlock Text="{Binding Source}"/>
<TextBlock Text="{Binding LineSpacing}"/>
<TextBlock Text="{Binding FamilyTypefaces[0].Style}"/>
<TextBlock Text="{Binding FamilyTypefaces[0].Weight}"/>
</StackPanel>
<TextBlock Text="{Binding Name}" HorizontalAlignment="Center"/>
<TextBlock Text="{Binding Age}" HorizontalAlignment="Center"/>
</StackPanel>
</Grid>
</Window>
4.总结
非元素对象绑定
│
├─ 1.Source(显式数据源)
│ │
│ ├─ 静态对象
│ │ x:Static
│ │ └─ SystemFonts.IconFontFamily
│ │
│ ├─ 资源对象
│ │ StaticResource
│ │ └─ ResourceDictionary
│ │
│ ├─ 普通对象
│ │ C# 类实例
│ │ └─ User
│ │
│ ├─ ObjectDataProvider
│ │ └─ 调用对象方法 / 属性
│ │
│ └─ x:Reference
│ └─ 引用 XAML 中已有对象实例
│
├─ 2.RelativeSource(相对数据源)
│ │
│ ├─ Self
│ │ └─ 绑定自己
│ │
│ ├─ FindAncestor
│ │ └─ 向 UI 树上查找祖先控件
│ │
│ ├─ TemplatedParent
│ │ └─ 访问模板宿主控件
│ │
│ └─ PreviousData
│ └─ 访问集合中上一条数据
│
└─ 3.DataContext(默认数据源)
│
├─ XAML 中设置
│ Window.DataContext
│ Grid.DataContext
│
├─ C# 中设置
│ this.DataContext = ViewModel
│
└─ 继承机制
Window
└─ Grid
└─ StackPanel
└─ TextBlock
Binding 数据来源
│
├─ ElementName
│ └─ 绑定到指定控件
│
├─ Source
│ └─ 显式指定对象
│
├─ RelativeSource
│ └─ 从 UI 树寻找对象
│
└─ DataContext
└─ 默认数据源(最常用)
随笔参考:
1.61.第8章_绑定到非元素_Source_哔哩哔哩_bilibili
2.62.第8章_绑定到非元素_RelativeSrouce_哔哩哔哩_bilibili
3.63.第8章_绑定到非元素_DataContext_哔哩哔哩_bilibili
哦吼吼吼!终于写完了,要死了要死了,最近这两篇博客,感觉写的实在是太久了,资料是越查越多,越查越多.....
多的让我以为世界快完蛋了,虽然是用来学习的同时,打发一下摸鱼时间
好吧,其实是打法摸鱼的时候顺便学一下架构.......
来源:https://www.cnblogs.com/leaf-7-scouts/p/19723791 |