WPF数据转换
在基本绑定中,信息从源到目标的传递过程中没有任何变化。这看起来是符合逻辑的,但我们并不总是希望出现这种行为。通常,数据源使用的是低级表达方式,我们可能不希望直接在用户界面使用这种低级表达方式。WPF提供了两个工具,来进行数据转换:
字符串格式化
通过设置 Binding.StringFormat 属性对文本形式的数据进行转换——例如包含日期和数字的字符串。
值转换器
该功能更强大,使用该功能可以将任意类型的源数据转换为任意类型的对象表示,然后可以传递到关联的控件。
使用StringFormat属性
<TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding Path=Price, StringFormat=ConvertDirectly:{0:C}}"></TextBlock>
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Path=Price, StringFormat={}{0:C}}"></TextBox>
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Path=OrderDate, StringFormat={}{0:s}}"></TextBox>
可以看到后面两个StringFormat属性以花括号 {} 开头,完整值是 {}{0:C},而不是 {0:C},第一个则只有 {0:C},这是因为在StringFormat 值以花括号开头时需要 {} 转义序列。
使用值转换器
为创建子转换器需要执行以下四个步骤:
1、创建一个实现IValueConverter接口的类
2、为该类声明添加ValueConversion特性,并指定目标数据类型
3、实现Convert()方法,该方法将数据从原来的格式转换为显示的格式
4、实现ConvertBack()方法,该方法执行反向变换,将值从显示格式转换为原格式
[ValueConversion(typeof(decimal), typeof(string))]
public class PriceConverter : IValueConverter
{public object Convert(object value, Type targetType, object parameter, CultureInfo culture){decimal price = (decimal)value;return price.ToString("C", culture);}public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture){string price = (string)value;if (decimal.TryParse(price, System.Globalization.NumberStyles.Any, culture, out decimal result)){return result;}return value;}
}
要使用这个转换器,可以将其添加到页面的资源下,然后使用 Binding.Converter 指定。
<Window><Window.Resources><local:PriceConverter x:Key="priceConverter"/><local:PriceToBackgroundConverter x:Key="priceToBackgroundConverter" MinimumPriceToHighlight="100" DefaultBrush="{x:Null}" HighlightBrush="Orange"/><local:ImagePathConverter x:Key="imagePathConverter"/><local:MultiValueConverter x:Key="multiValueConverter"/></Window.Resources><TextBox Text="{Binding Path=Price, Converter={StaticResource priceConverter}}"></TextBox>
</Window>
多重绑定
可以将多个字段绑定到同一个输出控件,可以通过 StringFormat 或 MultiBinding.Converter 来格式化数据。多重绑定的值转换器需要实现的接口是 IMultiValueConverter,与 IValueConverter 接口比较类似,只是转换函数的第一个参数改成了数组形式。
<TextBlock Grid.Row="4" Grid.Column="0"><TextBlock.Text><MultiBinding StringFormat="{}{0}, {1}, {2}"><Binding Path="Price"/><Binding Path="OrderDate"/><Binding Path="Volume"/></MultiBinding></TextBlock.Text></TextBlock><TextBlock Grid.Row="5" Grid.Column="0"><TextBlock.Text><MultiBinding Converter="{StaticResource multiValueConverter}"><Binding Path="Price"/><Binding Path="Volume"/></MultiBinding></TextBlock.Text></TextBlock>
public class MultiValueConverter : IMultiValueConverter
{public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture){decimal price = (decimal)values[0];int volume = (int)values[1];return (price * volume).ToString("C");}public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture){throw new NotSupportedException();}
}
完整代码如下:
MainWindow.xaml
<Window x:Class="TestDataConverter.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:TestDataConverter"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800"><Window.Resources><local:PriceConverter x:Key="priceConverter"/><local:PriceToBackgroundConverter x:Key="priceToBackgroundConverter" MinimumPriceToHighlight="100" DefaultBrush="{x:Null}" HighlightBrush="Orange"/><local:ImagePathConverter x:Key="imagePathConverter"/><local:MultiValueConverter x:Key="multiValueConverter"/></Window.Resources><Grid Name="myGrid" Background="{Binding Path=Price, Converter={StaticResource priceToBackgroundConverter}}"><Grid.ColumnDefinitions><ColumnDefinition/><ColumnDefinition/></Grid.ColumnDefinitions><Grid.RowDefinitions><RowDefinition/><RowDefinition/><RowDefinition/><RowDefinition/><RowDefinition/><RowDefinition/></Grid.RowDefinitions><TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding Path=Price, StringFormat=ConvertDirectly:{0:C}}"></TextBlock><TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Path=Price, StringFormat={}{0:C}}"></TextBox><TextBlock Grid.Row="1" Grid.Column="0">ConvertWithConverter:</TextBlock><TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Path=Price, Converter={StaticResource priceConverter}}"></TextBox><TextBlock Grid.Row="2" Grid.Column="0">ConvertDateTime:</TextBlock><TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Path=OrderDate, StringFormat={}{0:s}}"></TextBox><TextBlock Grid.Row="3" Grid.Column="0">ConvertImagePath:</TextBlock><Image Grid.Row="3" Grid.Column="1" Stretch="None" HorizontalAlignment="Left" Source="{Binding Path=Image, Converter={StaticResource imagePathConverter}}"></Image><TextBlock Grid.Row="4" Grid.Column="0"><TextBlock.Text><MultiBinding StringFormat="{}{0}, {1}, {2}"><Binding Path="Price"/><Binding Path="OrderDate"/><Binding Path="Volume"/></MultiBinding></TextBlock.Text></TextBlock><TextBlock Grid.Row="5" Grid.Column="0"><TextBlock.Text><MultiBinding Converter="{StaticResource multiValueConverter}"><Binding Path="Price"/><Binding Path="Volume"/></MultiBinding></TextBlock.Text></TextBlock></Grid>
</Window>
MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Imaging;namespace TestDataConverter;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 Order : ViewModelBase
{public decimal price = 0;public decimal Price { get => price; set => SetProperty(ref price, value); }public int volume = 0;public int Volume { get => volume; set => SetProperty(ref volume, value); }public DateTime orderDate = DateTime.Now;public DateTime OrderDate { get => orderDate; set => SetProperty(ref orderDate, value); }public string image = string.Empty;public string Image { get => image; set => SetProperty(ref image, value); }
}
[ValueConversion(typeof(decimal), typeof(string))]
public class PriceConverter : IValueConverter
{public object Convert(object value, Type targetType, object parameter, CultureInfo culture){decimal price = (decimal)value;return price.ToString("C", culture);}public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture){string price = (string)value;if (decimal.TryParse(price, System.Globalization.NumberStyles.Any, culture, out decimal result)){return result;}return value;}
}
[ValueConversion(typeof(decimal), typeof(Brush))]
public class PriceToBackgroundConverter : IValueConverter
{public decimal MinimumPriceToHighlight { get; set; }public Brush HighlightBrush { get; set; }public Brush DefaultBrush { get; set; }public object Convert(object value, Type targetType, object parameter,System.Globalization.CultureInfo culture){decimal price = (decimal)value;if (price >= MinimumPriceToHighlight)return HighlightBrush;elsereturn DefaultBrush;}public object ConvertBack(object value, Type targetType, object parameter,System.Globalization.CultureInfo culture){throw new NotSupportedException();}
}
public class ImagePathConverter : IValueConverter
{private string imageDirectory = Directory.GetCurrentDirectory();public string ImageDirectory{get { return imageDirectory; }set { imageDirectory = value; }}public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture){string imagePath = Path.Combine(ImageDirectory, (string)value);return new BitmapImage(new Uri(imagePath));}public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture){throw new NotSupportedException("The method or operation is not implemented.");}
}
public class MultiValueConverter : IMultiValueConverter
{public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture){decimal price = (decimal)values[0];int volume = (int)values[1];return (price * volume).ToString("C");}public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture){throw new NotSupportedException();}
}public partial class MainWindow : Window
{public MainWindow(){InitializeComponent();myGrid.DataContext = Order;Order.Price = 100;Order.Volume = 10;Order.OrderDate = DateTime.Now;Order.Image = "image1.gif";}public Order Order = new Order();private void Button_Click(object sender, RoutedEventArgs e){Console.WriteLine("");}
}
相关文章:
WPF数据转换
在基本绑定中,信息从源到目标的传递过程中没有任何变化。这看起来是符合逻辑的,但我们并不总是希望出现这种行为。通常,数据源使用的是低级表达方式,我们可能不希望直接在用户界面使用这种低级表达方式。WPF提供了两个工具&#x…...
《Go 语言第一课》课程学习笔记(十三)
方法 认识 Go 方法 Go 语言从设计伊始,就不支持经典的面向对象语法元素,比如类、对象、继承,等等,但 Go 语言仍保留了名为“方法(method)”的语法元素。当然,Go 语言中的方法和面向对象中的方…...
基于RUM高效治理网站用户体验入门-价值篇
用户体验 用户体验基本包含访问网站的性能、可用性和正确性。通俗的讲,就是一把通过用户访问测量【设计者】意图的尺子。 本文目的 网站如何传递出设计者的意图,可能页面加载时间太长、或者页面在用户的浏览器中渲染时间太慢,或者第三方设备…...
Unity之Photon PUN2开发多人游戏如何实现组队功能
前言 Photon Unity Networking 2 (PUN2) 是一款基于Photon Cloud的Unity多人游戏开发框架。它提供了一系列易于使用的API和工具,使开发者可以快速构建多人戏,并轻松处理多人游戏中的网络同步、房间管理、玩家匹配等问题。 我们在查看Pun2的Demo时,会发现Demo中自带了一个简…...
大数据Flink简介与架构剖析并搭建基础运行环境
文章目录 前言Flink 简介Flink 集群剖析Flink应用场景Flink基础运行环境搭建Docker安装docker-compose文件编写创建并运行容器访问Flink web界面 前言 前面我们分别介绍了大数据计算框架Hadoop与Spark,虽然他们有的有着良好的分布式文件系统和分布式计算引擎,有的有…...
RISC-V IOPMP实际用例-Rapid-k模型在NVIDIA上的应用
安全之安全(security)博客目录导读 2023 RISC-V中国峰会 安全相关议题汇总 说明:本文参考RISC-V 2023中国峰会如下议题,版权归原作者所有。...
【UE5】给模型指定面添加自定义材质
实现步骤 1. 首先我们向UE中导入一个简单的模型,可以看到目前该模型的材质插槽只有一个,当我们修改材质时会使得模型整体的材质全部改变,如果我们只想改变模型的某些面的材质就需要继续做后续操作。 2. 选择建模模式 3. 在模式工具栏中点击…...
mall:redis项目源码解析
文章目录 一、mall开源项目1.1 来源1.2 项目转移1.3 项目克隆 二、Redis 非关系型数据库2.1 Redis简介2.2 分布式后端项目的使用流程2.3 分布式后端项目的使用场景2.4 常见的缓存问题 三、源码解析3.1 集成与配置3.1.1 导入依赖3.1.2 添加配置3.1.3 全局跨域配置 3.2 Redis测试…...
RISC-V Linux系统kernel制作
文章目录 1、下载2、编译 1、下载 Linux 官网地址:https://www.kernel.org $ wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.10.181.tar.xz $ tar xvf linux-5.10.181.tar.xz $ cd linux-5.10.1812、编译 安装依赖 $ sudo apt-get install -y flex bison bui…...
5G NR:PRACH时域资源
PRACH occasion时域位置由高层参数RACH-ConfigGeneric->prach-ConfigurationIndex指示,根据小区不同的频域和模式,38.211的第6.3.3节中给出了prach-ConfigurationIndex所对应的表格。 小区频段为FR1,FDD模式(paired频谱)/SUL,…...
LLaMA-2的模型架构
输入token;[B, L] 输出probs:[B, L, vab_size]...
掌握Java框架之Struts,开启高效开发之旅!
当今的软件开发世界,Java框架如Struts已经成为构建企业级应用的重要工具。Struts作为一个流行的MVC框架,不仅简化了Java Web开发,还提高了软件的可维护性和可扩展性。本文将带你走进Struts的世界,探索其魅力所在,让你领…...
关于Vue.set()
简介 Vue.set() 是 Vue 中的一个全局方法,其主要作用是向响应式对象添加新的属性,并确保新属性同样具有响应式。在 Vue.js 中,当数据对象的属性被直接修改时,Vue 可以监测到数据变化并响应变化。但若添加新的响应式对象属性时&am…...
Selenium 遇见伪元素该如何处理?
问题发生 在很多前端页面中,大家会见到很多::before、::after 元素,比如【百度流量研究院】: 比如【百度疫情大数据平台】: 以【百度疫情大数据平台】为例,“累计确诊”文本并没有显示在 HTML 源代码中&am…...
RPA技术介绍与应用价值
一、什么是RPA技术? RPA(Robotic Process Automation)机器人流程自动化,是一种能够模拟人类来执行重复性任务的新型技术。RPA可实现统筹安排、自动化业务处理,并提升业务工作流处理效率。用户只需通过图形方式显示的计算机操作界面对RPA软件进行动态设定即可。借助RPA (R…...
产品经理,需要具备哪些能力和知识
作为产品经理,需要具备以下能力和知识: 产品管理能力:具备全面的产品管理能力,包括产品策划、需求分析、产品规划、产品设计、项目管理、市场调研和竞争分析等。 用户导向思维:能够理解用户需求和期望,以…...
【C++】map和set
map和set 文章目录 map和set关联式容器setset介绍set的函数测试代码 multiset注意事项测试代码 mapmap介绍map的函数测试代码 关联式容器 前面了解过的vector,list,string等容器都是序列式容器,存储的都是元素本身,底层都是线性的…...
crawlab通过docker单节点部署简单爬虫
crawlab 单节点docker安装 此处介绍的是单节点的方式,多节点的情况可以把爬虫上传到一个节点中,之后会同步到其它节点上 version: 3.3 services:master:image: crawlabteam/crawlabcontainer_name: crawlab_masterrestart: alwaysenvironment:CRAWLAB…...
【STM32】中断与NVIC以外部中断为例
前言 在stm32中姑且可以认为,异常就是中断 单片机上电之后,首先执行启动文件,开辟堆栈之后,开始初始化中断向量表。 NVIC NVIC NVIC是嵌套向量中断控制器,控制着整个芯片中断相关的功能,它跟内核紧密耦…...
大学生网页设计制作作业实例代码 (全网最全,建议收藏) HTML+CSS+JS
文章目录 📚web前端期末大作业 (1500套) 集合一、网页介绍二、网页集合 三、作品演示A电影主题B漫画主题C商城主题D家乡主题E旅游主题F餐饮/美食主题G环境主题H游戏主题I 个人主题K体育主题L博客主题M汽车主题N文化主题P美妆主题Q企业主题R教育主题S其他主题 &#…...
Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机
这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...
