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其他主题 &#…...
利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
ubuntu系统文件误删(/lib/x86_64-linux-gnu/libc.so.6)修复方案 [成功解决]
报错信息:libc.so.6: cannot open shared object file: No such file or directory: #ls, ln, sudo...命令都不能用 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory重启后报错信息&…...
云原生周刊:k0s 成为 CNCF 沙箱项目
开源项目推荐 HAMi HAMi(原名 k8s‑vGPU‑scheduler)是一款 CNCF Sandbox 级别的开源 K8s 中间件,通过虚拟化 GPU/NPU 等异构设备并支持内存、计算核心时间片隔离及共享调度,为容器提供统一接口,实现细粒度资源配额…...
消防一体化安全管控平台:构建消防“一张图”和APP统一管理
在城市的某个角落,一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延,滚滚浓烟弥漫开来,周围群众的生命财产安全受到严重威胁。就在这千钧一发之际,消防救援队伍迅速行动,而豪越科技消防一体化安全管控平台构建的消防“…...
Python常用模块:time、os、shutil与flask初探
一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...
大数据治理的常见方式
大数据治理的常见方式 大数据治理是确保数据质量、安全性和可用性的系统性方法,以下是几种常见的治理方式: 1. 数据质量管理 核心方法: 数据校验:建立数据校验规则(格式、范围、一致性等)数据清洗&…...
【java面试】微服务篇
【java面试】微服务篇 一、总体框架二、Springcloud(一)Springcloud五大组件(二)服务注册和发现1、Eureka2、Nacos (三)负载均衡1、Ribbon负载均衡流程2、Ribbon负载均衡策略3、自定义负载均衡策略4、总结 …...
