当前位置: 首页 > news >正文

WPF数据绑定

数据绑定是一个很强大且优雅的技能,之前用过好多次,但有些地方总不是特别清晰,常常需要重新翻阅资料来回顾,于是这次用了几天时间好好梳理一下,记录一下。

首先数据绑定对数据对象的要求:需要是公有属性(不支持字段和私有属性)。

如果需要在数据内容发生变化时自动更新到控件,则需要实现INotifyPropertyChanged接口,其包含 PropertyChanged事件,在属性变化时引发PropertyChanged事件。

如果绑定对象为集合时,需要在集合内容发生变化时自动更新到控件,则需要INotifyCollectionChanged接口,其包含CollectionChanged事件,目前内置的泛型集合 ObservableCollection 实现了该接口。

通常在设置绑定时,我们需要指定数据上下文,DataContext,如果控件没有设置DataContext,则会去找父容器的DataContext,依层级依次查找。也有些控件直接在代码中指定ItemsSource的。如果要绑定的数据依赖于另外一个控件的值,可以在DataContext中,绑定到另外一个控件的选中项,然后设置该控件的数据源或者绑定值。

MainWindow.xaml

<Window x:Class="TestBinding.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:TestBinding"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800"><StackPanel Name="parentContainer"><StackPanel Orientation="Horizontal"><TextBlock>BindData:</TextBlock><TextBox Text="{Binding Path=BindData}"></TextBox></StackPanel><StackPanel Orientation="Horizontal"><TextBlock>BindDatas:</TextBlock><ListBox Name="exchangeListBox" ItemsSource="{Binding Path=Exchanges}" DisplayMemberPath="ExchangeID"></ListBox></StackPanel><StackPanel><ComboBox Name="instrumentCombbox" DataContext="{Binding ElementName=exchangeListBox, Path=SelectedItem}" ItemsSource="{Binding Path=Instruments}" DisplayMemberPath="InstrumentID"/></StackPanel><StackPanel Orientation="Horizontal" DataContext="{Binding ElementName=instrumentCombbox, Path=SelectedItem}"><TextBlock>ExchangeID:</TextBlock><TextBox Text="{Binding Path=ExchangeID}"></TextBox></StackPanel><StackPanel Orientation="Horizontal" DataContext="{Binding ElementName=instrumentCombbox, Path=SelectedItem}"><TextBlock>InstrumentID:</TextBlock><TextBox Text="{Binding Path=InstrumentID}"></TextBox></StackPanel><StackPanel Orientation="Horizontal" DataContext="{Binding ElementName=instrumentCombbox, Path=SelectedItem}"><TextBlock>InstrumentName:</TextBlock><TextBox Text="{Binding Path=InstrumentName}"></TextBox></StackPanel></StackPanel>
</Window>

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;namespace TestBinding;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 SetProperty<T>(ref T member, T value, [CallerMemberName] string? propertyName = null){if (EqualityComparer<T>.Default.Equals(member, value)){return false;}member = value;OnPropertyChanged(propertyName);return true;}
}
public class ExchangeViewModel : ViewModelBase
{private string exchangeID = string.Empty;public string ExchangeID { get => exchangeID; set => SetProperty(ref exchangeID, value); }public ObservableCollection<InstrumentViewModel> Instruments { get; set; } = new ObservableCollection<InstrumentViewModel>();
}
public class InstrumentViewModel : ViewModelBase
{public InstrumentViewModel(string exchangeID, string instrumentID, string instrumentName){ExchangeID = exchangeID;InstrumentID = instrumentID;InstrumentName = instrumentName;}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); }
}
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{public MainWindow(){InitializeComponent();parentContainer.DataContext = this;Exchanges = new();ExchangeViewModel exchange1 = new ExchangeViewModel();exchange1.ExchangeID = "SHSE";exchange1.Instruments.Add(new InstrumentViewModel("SHSE", "601155", "新城控股"));exchange1.Instruments.Add(new InstrumentViewModel("SHSE", "600036", "招商银行"));exchange1.Instruments.Add(new InstrumentViewModel("SHSE", "600266", "城建发展"));exchange1.Instruments.Add(new InstrumentViewModel("SHSE", "600837", "海通证券"));exchange1.Instruments.Add(new InstrumentViewModel("SHSE", "601668", "中国建筑"));ExchangeViewModel exchange2 = new ExchangeViewModel();exchange2.ExchangeID = "SZSE";exchange2.Instruments.Add(new InstrumentViewModel("SZSE", "000002", "万科A"));exchange2.Instruments.Add(new InstrumentViewModel("SZSE", "000001", "平安银行"));exchange2.Instruments.Add(new InstrumentViewModel("SZSE", "000623", "吉林敖东"));exchange2.Instruments.Add(new InstrumentViewModel("SZSE", "002739", "万达电影"));exchange2.Instruments.Add(new InstrumentViewModel("SZSE", "300642", "透景生命"));Exchanges.Add(exchange1);Exchanges.Add(exchange2);}public string BindData { get; set; } = "BindData";public ObservableCollection<ExchangeViewModel> Exchanges { get; set; }
}

相关文章:

WPF数据绑定

数据绑定是一个很强大且优雅的技能&#xff0c;之前用过好多次&#xff0c;但有些地方总不是特别清晰&#xff0c;常常需要重新翻阅资料来回顾&#xff0c;于是这次用了几天时间好好梳理一下&#xff0c;记录一下。 首先数据绑定对数据对象的要求&#xff1a;需要是公有属性&a…...

Android学习之路(6) 其他UI控件

ImageView(图像视图) RadioButton(单选按钮)&Checkbox(复选框) 开关按钮ToggleButton和开关Switch ProgressBar(进度条) SeekBar(拖动条) RatingBar(星级评分条) ScrollView(滚动条)...

matlab实现牛顿迭代法求解非线性方程

非线性方程是指含有未知数的方程&#xff0c;且方程中至少有一个未知数的次数大于一或者含有非一次幂的函数&#xff08;如指数、对数、三角函数等&#xff09;。例如&#xff0c;$f(x) x^3 - 2x - 5 0$就是一个非线性方程。非线性方程通常没有显式的解析解&#xff0c;因此需…...

Cpp学习——编译链接

目录 ​编辑 一&#xff0c;两种环境 二&#xff0c;编译环境下四个部分的 1.预处理 2.编译 3.汇编 4.链接 三&#xff0c;执行环境 一&#xff0c;两种环境 在程序运行时会有两种环境。第一种便是编译环境&#xff0c;第二种则是执行环境。如下图&#xff1a; 在程序运…...

android - fragment 数据丢失?状态丢失?

最佳答案 一些状态丢失的例子: 1. 假设您有一个按钮和一个 TextView 。在代码中&#xff0c;你已经定义了初始值为 0 的整数 i&#xff0c;它通过单击按钮递增 1&#xff0c;并且它的值显示在 TextView 中。假设你已经按下按钮 5 次&#xff0c;那么 textview 将被设置为 0。也…...

Git基本操作

本地仓库 当我们初始化&#xff08;git init&#xff09;之后&#xff0c;会在当前目录下生成一个与项目并列的.git文件夹&#xff0c;当我们对项目作出更改之后使用git commit命令&#xff0c;一般是将修改提交到本地仓库&#xff0c;也就是该文件夹下面的文件会对应修改&…...

Nginx配置文件详解

Nginx配置文件详解 1、Nginx配置文件1.1主配置文件详解1.2子配置文件 2、全局配置部分2.1修改启动的工作进程数&#xff08;worker process) 优化2.2cpu与worker process绑定2.3 PID 路径修改2.4 修改工作进程的优先级2.5调试工作进程打开的文件的个数2.6关闭master-worker工作…...

【0217】stats collector(统计信息收集器)进程启动原理(1)

文章目录 1. 启动 stats collector进程1.1 stats collector进程启动过程1.1.1 检查套接字 pgStatSock 是否存在1.1.2 重新启动失败的stats collector频率1.1.3 fork() 三种返回值处理1.2 detach所有共享内存段1.3 detach 共享内存段1.4 stats collecotr进程启动的主体相关阅读:…...

【应用层】网络基础 -- HTTPS协议

HTTPS 协议原理加密为什么要加密常见的加密方式对称加密非对称加密 数据摘要&&数据指纹 HTTPS 的工作过程探究方案1-只使用对称加密方案2-只使用非对称加密方案3-双方都使用非对称加密方案4-非对称加密对称加密中间人攻击-针对上面的场景 CA认证理解数据签名方案5-非对…...

实验篇—— 基因家族Motif 分析

实验篇—— 基因家族Motif 分析 文章目录 前言一、名词解释二、实操1. MEME工具箱2. Motif Discovery&#xff08;基序发现&#xff09;1. 结果网页2. 在TBtools中&#xff08;额外&#xff09; 2. Motif Enrichment&#xff08;基序富集分析&#xff09;3. Motif Search&#…...

Linux拓展之阻止或禁用普通用户登录

禁止指定用户登录 chsh -s /sbin/nologin 指定用户名示例 chsh -s /sbin/nologin testuser恢复指定用户登录 chsh -s /bin/bash 指定用户名示例 chsh -s /bin/bash testuser参考 https://blog.csdn.net/cnds123321/article/details/125232580 https://www.cnblogs.com/cai…...

Linux系统USB摄像头测试程序(四)_视频旋转及缩放

下面的程序实现了视频的旋转及缩放&#xff0c;窗口中点击鼠标左键视频向左旋转&#xff0c;点击鼠标右键视频向右旋转并且视频缩小了二分之一。程序中首先把yvyv422转换成了RGB24&#xff0c;然后利用opencv进行了旋转和缩放&#xff0c;其后用sdl2进行了渲染。使用了ffmpeg、…...

大模型+学习机,是概念游戏还是双向奔赴?

众所周知&#xff0c;2023年上半年大模型概念炙手可热。各大科技公司纷纷卷入&#xff0c;或宣称布局相关领域&#xff0c;或率先官宣自研大模型。而随着资本市场对大模型概念的热情有所消退&#xff0c;属于这片战场的新一轮角逐慢慢聚焦在了技术的落地应用上。 8月15日&#…...

linux怎么查看用户属于哪个组

查看当前用户所属组 shell> groups root查看指定用户所属组 shell> groups testuser testuser : testusershell> id testuser uid1000(testuser) gid1000(testuser) groups1000(testuser)查看组文件 shell> cat /etc/group...

邂逅JavaScript

前言&#xff1a;前端三大核心 前端开发最主要需要掌握的是三个知识点&#xff1a;HTML、CSS、JavaScript 一、认识编程语言 1.计算机语言 前面我们已经学习了HTML和CSS很多相关的知识: 在之前我们提到过, HTML是一种标记语言, CSS也是一种样式语言; 他们本身都是属于计算…...

Android 中 Fragment判空

1. 判断 Fragment 是否已经被添加到 Activity 中&#xff0c;可以通过 Fragment 的 isAdded() 方法来判断。 2. 判断 Fragment 的 View 是否已经被创建&#xff0c;可以通过 Fragment 的 getView() 方法来判断。 3. 判断 Fragment 是否已经被销毁&#xff0c;可以通过 Fragme…...

软考高级系统架构设计师系列论文八十八:财务数据仓库系统的设计与实现

软考高级系统架构设计师系列论文八十八:财务数据仓库系统的设计与实现 一、摘要二、正文三、总结一、摘要 近年来,数据仓库技术在信息系统的建设中得到了广泛应用,有效地为决策提供了支持。2020年6月,本人所在单位组织开发了财务管理决策系统,该系统主要是使高层领导掌握企…...

fastdeploy部署多线程/进程paddle ocr(python flask框架 )

部署参考&#xff1a;https://github.com/PaddlePaddle/FastDeploy/blob/develop/tutorials/multi_thread/python/pipeline/README_CN.md 安装 cpu&#xff1a; pip install fastdeploy-python gpu &#xff1a;pip install fastdeploy-gpu-python #下载部署示例代码 git cl…...

【图论】拓扑排序

一.定义 拓扑排序是一种对有向无环图&#xff08;DAG&#xff09;进行排序的算法&#xff0c;使得图中的每个顶点在排序中都位于其依赖的顶点之后。它通常用于表示一些任务之间的依赖关系&#xff0c;例如在一个项目中&#xff0c;某些任务必须在其他任务之前完成。 拓扑排序的…...

自动化备份方案

背景说明 网上有很多教程&#xff0c;写的都是从零搭建一个什么什么&#xff0c;基本上都是从无到有的教程&#xff0c;但是&#xff0c;很少有文章提及搭建好之后如何备份&#xff0c;这次通过请教GitHub Copilot Chat&#xff0c;生成几个备份脚本&#xff0c;以备后用。 注…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

【Java学习笔记】BigInteger 和 BigDecimal 类

BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点&#xff1a;传参类型必须是类对象 一、BigInteger 1. 作用&#xff1a;适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

管理学院权限管理系统开发总结

文章目录 &#x1f393; 管理学院权限管理系统开发总结 - 现代化Web应用实践之路&#x1f4dd; 项目概述&#x1f3d7;️ 技术架构设计后端技术栈前端技术栈 &#x1f4a1; 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 &#x1f5c4;️ 数据库设…...