WPF数据模板
样式提供了基本的格式化能力,但它们不能消除到目前为止看到的列表的最重要的局限性:不管如何修改ListBoxItem,它都只是ListBoxItem,而不是功能更强大的元素组合。并且因为每个ListBoxItem只支持单个绑定字段,所以不可能实现包含多个字段或图像的富列表。
然而WPF另有一个工具可突破这个相当大的限制,并允许组合使用来自绑定对象的多个属性,并以特定的方式排列它们或显示比简单字符串更高级的可视化表示。这个工具就是数据模板。
数据模板是一块定义如何显示绑定的数据对象的XAML标记。有两种类型的控件支持数据模板:
内容控件 通过ContentTemplate属性支持数据模板。内容模板用于显示任何放置在Content属性中的内容。
列表控件(继承自ItemsControl类的控件) 通过ItemsTemplate属性支持数据模板。这个模板用于显示作为ItemsSource提供的集合中的每个项(或来自DataTable的每一行)。
基于列表的模板特性实际上以内容控件模板为基础,这是因为列表中的每个项均由内容控件封装。数据模板是一块普通的XAML标记。与其他XAML标记一样,数据模板可以包含任意元素的组合,还应当包含一个或多个数据绑定表达式,从而提取希望显示的信息。
分离和重用模板
数据模板可以写在应用模板控件标签下,也可以放在资源内作为公共资源,以便复用。放在资源标签内时,可以指定模板的Key并在应用控件里面通过Key关联模板,与常规的资源没什么两样;也可以指定DataType属性,会自动应用于绑定与DataType指定的数据类型相同的控件。
<DataTemplate x:Key="highlightTemplate" DataType="{x:Type local:Order}" ><Grid Margin="0" Background="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem} }, Path=Background}"><Border Margin="5" BorderThickness="1" BorderBrush="SteelBlue" Background="LightYellow" CornerRadius="4"><Grid Margin="3"><Grid.RowDefinitions><RowDefinition></RowDefinition><RowDefinition></RowDefinition><RowDefinition></RowDefinition></Grid.RowDefinitions><TextBlock Grid.Row="0" FontWeight="Bold" Text="{Binding Path=Price}" /><TextBlock Grid.Row="1" FontWeight="Bold" Text="{Binding Path=Volume}" /><TextBlock Grid.Row="2" FontStyle="Italic" HorizontalAlignment="Right">*** Great for vacations ***</TextBlock></Grid></Border></Grid>
</DataTemplate>
改变模板
可以通过几种方式为同一个列表使用不同的模板
数据触发器 可根据绑定的数据对象中的属性值使用触发器修改模板中的属性。
值转换器 实现了IValueConverter接口的类,能够将值从绑定的对象转换为可用于设置模板中与格式化相关的属性的值。
模板选择器 模板选择器检查绑定的数据对象,并在几个不同模板之间进行选择。
数据触发器提供了最简单的方法。基本技术是根据数据项中的某个属性,设置模板中某个元素的某个属性。这种方法非常有用,但是不能改变与模板相关的复杂细节,只能修改模板或容器元素中的单个属性。此外触发器只能测试是否相等,不支持更复杂的比较条件。
<DataTemplate DataType="{x:Type local:Order}" ><DataTemplate.Triggers><DataTrigger Binding="{Binding Path=Price}" Value="1000"><Setter Property="ListBoxItem.Foreground" Value="Red"></Setter><Setter Property="ListBoxItem.FontStyle" Value="Italic"></Setter></DataTrigger></DataTemplate.Triggers>
</DataTemplate>
值转换器在数据转换里面介绍过了,通过Converter属性设置,可以根据绑定的对象调整自身。
<Image Grid.Column="1" Grid.RowSpan="2" Source="{Binding Path=Image, Converter={StaticResource ImagePathConverter}}"></Image>
模板选择器是一种更强大的工具,可以根据不同的条件应用完全不同的模板。模板选择器继承自DataTemplateSelector,需要实现 SelectTemplate() 函数,返回应用的DataTemplate。
public class SingleCriteriaHighlightTemplateSelector : DataTemplateSelector
{public System.Windows.DataTemplate DefaultTemplate { get; set; }public System.Windows.DataTemplate HighlightTemplate { get; set; }public override System.Windows.DataTemplate SelectTemplate(object item, DependencyObject container){Order order = (Order)item;if (order.Price >= 10000){return HighlightTemplate;}else{return DefaultTemplate;}}
}
<Window><Window.Resources><DataTemplate x:Key="defaultTemplate" DataType="{x:Type local:Order}" ><DataTemplate.Triggers><DataTrigger Binding="{Binding Path=Price}" Value="1000"><Setter Property="ListBoxItem.Foreground" Value="Red"></Setter></DataTrigger></DataTemplate.Triggers><Grid Margin="0" Background="White"><Border Margin="5" BorderThickness="1" BorderBrush="SteelBlue"Background="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem} }, Path=Background}" CornerRadius="4"><Grid Margin="3"><Grid.ColumnDefinitions><ColumnDefinition/><ColumnDefinition/></Grid.ColumnDefinitions><Grid.RowDefinitions><RowDefinition></RowDefinition><RowDefinition></RowDefinition><RowDefinition></RowDefinition></Grid.RowDefinitions><TextBlock FontWeight="Bold" Text="{Binding Path=Price}"></TextBlock><TextBlock Grid.Row="1" Text="{Binding Path=Volume}"></TextBlock><Image Grid.Column="1" Grid.RowSpan="2" Source="{Binding Path=Image, Converter={StaticResource ImagePathConverter}}"></Image></Grid></Border></Grid></DataTemplate><DataTemplate x:Key="highlightTemplate" DataType="{x:Type local:Order}" ><Grid Margin="0" Background="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem} }, Path=Background}"><Border Margin="5" BorderThickness="1" BorderBrush="SteelBlue" Background="LightYellow" CornerRadius="4"><Grid Margin="3"><Grid.RowDefinitions><RowDefinition></RowDefinition><RowDefinition></RowDefinition><RowDefinition></RowDefinition></Grid.RowDefinitions><TextBlock Grid.Row="0" FontWeight="Bold" Text="{Binding Path=Price}" /><TextBlock Grid.Row="1" FontWeight="Bold" Text="{Binding Path=Volume}" /><TextBlock Grid.Row="2" FontStyle="Italic" HorizontalAlignment="Right">*** Great for vacations ***</TextBlock></Grid></Border></Grid></DataTemplate></Window.Resources><ListBox Grid.Row="0" Grid.Column="1" ItemsSource="{Binding Path=Orders}" ItemContainerStyle="{StaticResource listBoxItemStyle}" HorizontalContentAlignment="Stretch"><ListBox.ItemTemplateSelector><local:SingleCriteriaHighlightTemplateSelector DefaultTemplate="{StaticResource defaultTemplate}" HighlightTemplate="{StaticResource highlightTemplate}"/></ListBox.ItemTemplateSelector></ListBox>
</Window>
完整代码如下:
MainWindow.xaml
<Window x:Class="DataTemplate.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:DataTemplate"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800"><Window.Resources><local:ImagePathConverter x:Key="ImagePathConverter"></local:ImagePathConverter><DataTemplate DataType="{x:Type local:Order}" ><DataTemplate.Triggers><DataTrigger Binding="{Binding Path=Price}" Value="1000"><Setter Property="ListBoxItem.Foreground" Value="Red"></Setter><Setter Property="ListBoxItem.FontStyle" Value="Italic"></Setter></DataTrigger></DataTemplate.Triggers><Grid Margin="0" ><Border Margin="5" BorderThickness="1" BorderBrush="SteelBlue"Background="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem} }, Path=Background}" CornerRadius="4"><Grid Margin="3"><Grid.ColumnDefinitions><ColumnDefinition/><ColumnDefinition/></Grid.ColumnDefinitions><Grid.RowDefinitions><RowDefinition></RowDefinition><RowDefinition></RowDefinition><RowDefinition></RowDefinition></Grid.RowDefinitions><TextBlock FontWeight="Bold" Text="{Binding Path=Price}"></TextBlock><TextBlock Grid.Row="1" Text="{Binding Path=Volume}"></TextBlock><Image Grid.Column="1" Grid.RowSpan="2" Source="{Binding Path=Image, Converter={StaticResource ImagePathConverter}}"></Image></Grid></Border></Grid></DataTemplate><DataTemplate x:Key="defaultTemplate" DataType="{x:Type local:Order}" ><DataTemplate.Triggers><DataTrigger Binding="{Binding Path=Price}" Value="1000"><Setter Property="ListBoxItem.Foreground" Value="Red"></Setter></DataTrigger></DataTemplate.Triggers><Grid Margin="0" Background="White"><Border Margin="5" BorderThickness="1" BorderBrush="SteelBlue"Background="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem} }, Path=Background}" CornerRadius="4"><Grid Margin="3"><Grid.ColumnDefinitions><ColumnDefinition/><ColumnDefinition/></Grid.ColumnDefinitions><Grid.RowDefinitions><RowDefinition></RowDefinition><RowDefinition></RowDefinition><RowDefinition></RowDefinition></Grid.RowDefinitions><TextBlock FontWeight="Bold" Text="{Binding Path=Price}"></TextBlock><TextBlock Grid.Row="1" Text="{Binding Path=Volume}"></TextBlock><Image Grid.Column="1" Grid.RowSpan="2" Source="{Binding Path=Image, Converter={StaticResource ImagePathConverter}}"></Image></Grid></Border></Grid></DataTemplate><DataTemplate x:Key="highlightTemplate" DataType="{x:Type local:Order}" ><Grid Margin="0" Background="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem} }, Path=Background}"><Border Margin="5" BorderThickness="1" BorderBrush="SteelBlue" Background="LightYellow" CornerRadius="4"><Grid Margin="3"><Grid.RowDefinitions><RowDefinition></RowDefinition><RowDefinition></RowDefinition><RowDefinition></RowDefinition></Grid.RowDefinitions><TextBlock Grid.Row="0" FontWeight="Bold" Text="{Binding Path=Price}" /><TextBlock Grid.Row="1" FontWeight="Bold" Text="{Binding Path=Volume}" /><TextBlock Grid.Row="2" FontStyle="Italic" HorizontalAlignment="Right">*** Great for vacations ***</TextBlock></Grid></Border></Grid></DataTemplate><Style x:Key="listBoxItemStyle" TargetType="{x:Type ListBoxItem}"><Setter Property="Control.Padding" Value="0"></Setter><Style.Triggers><Trigger Property="ListBoxItem.IsSelected" Value="True"><Setter Property="ListBoxItem.Background" Value="DarkRed" /></Trigger></Style.Triggers></Style></Window.Resources><Grid Name="myGrid" ><Grid.ColumnDefinitions><ColumnDefinition /><ColumnDefinition /></Grid.ColumnDefinitions><Grid.RowDefinitions><RowDefinition /><RowDefinition /></Grid.RowDefinitions><ListBox Grid.Row="0" Grid.Column="0" ItemsSource="{Binding Path=Orders}" ItemContainerStyle="{StaticResource listBoxItemStyle}" HorizontalContentAlignment="Stretch"/><ListBox Grid.Row="0" Grid.Column="1" ItemsSource="{Binding Path=Orders}" ItemContainerStyle="{StaticResource listBoxItemStyle}" HorizontalContentAlignment="Stretch"><ListBox.ItemTemplateSelector><local:SingleCriteriaHighlightTemplateSelector DefaultTemplate="{StaticResource defaultTemplate}" HighlightTemplate="{StaticResource highlightTemplate}"/></ListBox.ItemTemplateSelector></ListBox><ListView Grid.Row="1" Grid.Column="0" ItemsSource="{Binding Path=Orders}" HorizontalContentAlignment="Stretch" ></ListView></Grid>
</Window>
MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media.Imaging;namespace DataTemplate;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); }
}
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 SingleCriteriaHighlightTemplateSelector : DataTemplateSelector
{public System.Windows.DataTemplate DefaultTemplate { get; set; }public System.Windows.DataTemplate HighlightTemplate { get; set; }public override System.Windows.DataTemplate SelectTemplate(object item, DependencyObject container){Order order = (Order)item;if (order.Price >= 10000){return HighlightTemplate;}else{return DefaultTemplate;}}
}public partial class MainWindow : Window
{public MainWindow(){InitializeComponent();myGrid.DataContext = this;Order order1 = new Order();Order order2 = new Order();Order order3 = new Order();Order order4 = new Order();order1.Price = 100;order1.Volume = 10;order1.Image = "image1.gif";order2.Price = 1000;order2.Volume = 100;order2.Image = "image2.gif";order3.Price = 10000;order3.Volume = 1000;order3.Image = "image3.gif";order4.Price = 100000;order4.Volume = 10000;order4.Image = "image4.gif";Orders.Add(order1);Orders.Add(order2);Orders.Add(order3);Orders.Add(order4);}public ObservableCollection<Order> Orders { get; set; } = new();
}
相关文章:
WPF数据模板
样式提供了基本的格式化能力,但它们不能消除到目前为止看到的列表的最重要的局限性:不管如何修改ListBoxItem,它都只是ListBoxItem,而不是功能更强大的元素组合。并且因为每个ListBoxItem只支持单个绑定字段,所以不可能…...

浙江绿农环境:将废弃矿山变耕地,为生态文明贡献力量
近年来,随着可持续发展理念在中国乃至全球的日益普及,浙江绿农生态环境有限公司以其独特的创新和实践,成为了绿色发展的典范,在奋进新时代、建设新天堂的背景下,绿农环境在杭州市固废治理行业迈出坚实的步伐࿰…...
HTML/CSS盒子模型
盒子:页面中的所有的元素(标签),都可以看做一个盒子,由盒子将页面中的元素包含在一个矩形区域内,通过盒子的视角更加方便的进行页面布局 盒子模型的组成: 内容区域(contentÿ…...
《Java面向对象程序设计》学习笔记——CSV文件的读写与处理
笔记汇总:《Java面向对象程序设计》学习笔记 笔记记录的不是非常详实,如果有补充的建议或纠错,请踊跃评论留言!!! 什么是CSV文件 CSV文件的定义 CSV 是英文 comma-separated values 的缩写࿰…...

opencv 案例05-基于二值图像分析(简单缺陷检测)
缺陷检测,分为两个部分,一个部分是提取指定的轮廓,第二个部分通过对比实现划痕检测与缺角检测。本次主要搞定第一部分,学会观察图像与提取图像ROI对象轮廓外接矩形与轮廓。 下面是基于二值图像分析的大致流程 读取图像将图像转换…...
Elasticsearch入门介绍
应用场景 1 它提供了强大的搜索功能,可以实现类似百度、谷歌等搜索。 2 可以搜索日志或者交易数据,用来分析商业趋势、搜集日志、分析系统瓶颈或者运行发展等等 3 可以提供预警功能(持续的查询分析某个数据,如果超过一定的值&a…...

QML Book 学习基础3(动画)
目录 主要动画元素 例子: 非线性动画 分组动画 Qt 动画是一种在 Qt 框架下创建交互式和引人入胜的图形用户界面的方法,我们可以认为是对某个基础元素的多个设置 主要动画元素 PropertyAnimation-属性值变化时的动画 NumberA…...

Lesson4-3:OpenCV图像特征提取与描述---SIFT/SURF算法
学习目标 理解 S I F T / S U R F SIFT/SURF SIFT/SURF算法的原理,能够使用 S I F T / S U R F SIFT/SURF SIFT/SURF进行关键点的检测 SIFT/SURF算法 1.1 SIFT原理 前面两节我们介绍了 H a r r i s Harris Harris和 S h i − T o m a s i Shi-Tomasi Shi−Tomasi…...
语言基础篇9——Python流程控制
流程控制 顺序结构、条件结构、循环结构,顺序结构由自上而下的语句构成,条件结构由if、match-case构成,循环结构由for、while构成。 if语句 flag 1 if flag 1:print("A") elif flag 2:print("B") else:print("…...
MATLAB算法实战应用案例精讲-【概念篇】构建数据指标方法(补充篇)
目录 前言 几个高频面试题目 指标与标签的区别 几个相关概念 数据域 业务过程...

【pyqt5界面化工具开发-12】QtDesigner图形化界面设计
目录 0x00 前言 一、启动程序 二、基础的使用 三、保存布局文件 四、加载UI文件 0x00 前言 关于QtDesigner工具的配置等步骤(网上链接也比较多) 下列链接非本人的(如果使用pip 在命令行安装过pyqt5以及tools,那么就可以跳过…...

CXL.mem S2M Message 释义
🔥点击查看精选 CXL 系列文章🔥 🔥点击进入【芯片设计验证】社区,查看更多精彩内容🔥 📢 声明: 🥭 作者主页:【MangoPapa的CSDN主页】。⚠️ 本文首发于CSDN,…...

设计模式—外观模式(Facade)
目录 一、什么是外观模式? 二、外观模式具有什么优点吗? 三、外观模式具有什么缺点呢? 四、什么时候使用外观模式? 五、代码展示 ①、股民炒股代码 ②、投资基金代码 ③外观模式 思维导图 一、什么是外观模式?…...
Stack Overflow开发者调查发布:AI将如何协助DevOps
Stack Overflow 发布了开创性的2023年度开发人员调查报告 [1]。报告对 90,000 多名开发人员进行了调查,全面展示了当前软件开发人员的体验。接下来,本文将重点介绍几项重要发现,即重要编程语言和工具偏好、人工智能在开发工作流程中的应用以及…...
去掉鼠标系列之二:Sublime Text快捷键使用指南
系列之二,Sublime Text。 Sublime Text 是我们常用的文本工具,常常要沉浸如其中使用,而不希望被鼠标打扰,所以也记录一下。 学会下面这些快捷键,基本上就不需要移动鼠标啦。 1,CtrlK,CtrlV …...
docker-compose安装node-exporter, prometheus, grafana
基础 exporter提供监控数据 prometheus拉取监控数据 grafana可视化监控数据 准备 全部操作在/root/mypromethus中执行 node_exporter docker-compose -f node-exporter.yaml up -d # web访问,查看node_exporter采集到的数据 http://192.168.1.102:9101/metrics…...

企业架构LNMP学习笔记10
1、Nginx版本,在实际的业务场景中,需要使用软件新版本的功能、特性。就需要对原有软件进行升级或重装系统。 Nginx的版本需要升级迭代。那么如何进行升级呢?线上服务器如何升级,我们选择稳定版本。 从nginx的1.14版本升级到ngin…...
[国产MCU]-W801开发实例-I2C控制器
I2C控制器 文章目录 I2C控制器1、I2C控制器介绍2、I2C驱动API2、I2C简单使用示例1、I2C控制器介绍 I2C总线是一种简单、双向二线同步串口总线。I2C总线设备之间通信只需两根线即可完成设备之间的数据传输。 I2C总线设备分为主机和从机,这取决于数据传输方向。I2C总线上的主机…...

植物根系基因组与数据分析
1.背景 这段内容主要是关于植物对干旱胁迫的反应,并介绍了生活在植物体内外以及根际的真菌和细菌的作用。然而,目前对这些真菌和细菌的稳定性了解甚少。作者通过调查微生物群落组成和微生物相关性的方法,对农业系统中真菌和细菌对干旱的抗性…...

2.3 数据模型
思维导图: 前言: 我的理解: 这段话介绍了概念模型和数据模型之间的关系,以及数据模型的定义和重要性。具体解读如下: 1. **概念模型**:它是一种描述现实世界数据关系的抽象模型,不依赖于任何…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...

深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...

2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

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

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...

技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...