当前位置: 首页 > 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;以备后用。 注…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...