WPF水流动画(使用转换器模拟逻辑门控制水流信号)

news2024/11/20 11:30:34

前言

在使用WPF绘制流程图并模拟水流动画时,往往既需要控制阀泵的开合,又要控制动画启停。倘若能够将阀泵的开合与动画播放建立逻辑关系,这样就能够让业务代码“专心”地去控制阀泵开关,而不需要处理界面的展示。

动画示例

说明:动画中蚂蚁线的显示与隐藏是通过属性绑定配合转换器实现的。

动画解析

1、示例中【进水阀】前是一直有水流信号的,因此只要【进水阀】开,阀后即显示水流动画(此动画受一个属性控制,用单值转换器【IValueConverter】即可);

2、【进水阀】开启后,任意一个【提升泵】开启,即可出现汇入【储水池】的水流。为了与现场情况保持一致,示例中三个泵分别对应一根支管,连接到总管。水流从泵出发,通过支管流入总管,最终汇入【储水池】。

动画实现

1、水流路径处理

①当只有一个【提升泵】开启时,不用考虑路径重叠的问题,水流动画可以由一条折线来完成。

以下为单泵开启时各个泵的水流路径:

②当有多个泵开启时,只有最左边开启的泵需要绘制完整折线,其余启动泵只需绘制【支管】的水流路线。

如下,三泵全开状态。【1#泵】绘制从泵到池的完整路径,【2#泵】【3#泵】只绘制支管路径:

如下,只有【2#泵】【3#泵】开启。【2#泵】绘制从泵到池的完整路径,【3#泵】只绘制支管路径:

2、逻辑整理

①对于【1#泵】,以上两种情况下的动画路径是相同的。动画仅受【进水阀】和【1#泵】两个开关量的影响,可将其控制逻辑等效为【与门】。

②对于【2#泵】【3#泵】,【进水阀】和泵自身的开关信号是水流动画开启的必要条件,形成第一道【与门】。第二道门则根据实际情况决定:若左侧有任意泵开启,则仅绘制支管路径,此路径的第二道门为【或门】;若左侧泵全部关闭,则绘制泵到水池的完整路径,此路径的第二道门为【或非门】。

3、逻辑门实现

逻辑门借助多值转换器(IMultiValueConverter)来实现。

①与门

internal class AndGateToVisibilityConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values.Any(a => !(bool)a))
        {
            return Visibility.Collapsed;
        }
        return Visibility.Visible;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

 ②或门

在属性绑定中,只能使用一个转换器,所以将【与门】的逻辑整合到【或门】中,需要进行第一道【与门】判定的参数索引通过ConverterParameter传入。

internal class OrGateToVisibilityConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        // parameter传入的是参与第一道“与门”判定的索引,多个索引之间用逗号隔开
        List<int> andGateIndexes = parameter == null
            ? new List<int>()
            : parameter.ToString().Split(',').Select(a => System.Convert.ToInt32(a)).ToList();

        // 先进行“与门”判定
        if (andGateIndexes.Any(a => !(bool)values[a]))
        {
            return Visibility.Collapsed;
        }

        // 排除“与门”判定索引,进行“或门”判定
        for (int i = 0; i < values.Length; i++)
        {
            if (!andGateIndexes.Contains(i) && (bool)values[i])
            {
                return Visibility.Visible;
            }
        }
        return Visibility.Collapsed;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

③或非门

同样将第一道【与门】判定整合到此转换器中。

internal class NOrGateToVisibilityConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        // parameter传入的是参与第一道“与门”判定的索引,多个索引之间用逗号隔开
        List<int> andGateIndexes = parameter == null
            ? new List<int>()
            : parameter.ToString().Split(',').Select(a => System.Convert.ToInt32(a)).ToList();

        // 先进行“与门”判定
        if (andGateIndexes.Any(a => !(bool)values[a]))
        {
            return Visibility.Collapsed;
        }

        // 排除“与门”判定索引,进行“或非门”判定
        for (int i = 0; i < values.Length; i++)
        {
            if (!andGateIndexes.Contains(i) && (bool)values[i])
            {
                return Visibility.Collapsed;
            }
        }
        return Visibility.Visible;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1683067.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024-5-4-从0到1手写配置中心Config之基于h2的config-server

添加依赖 新建的web工程中添加h2的依赖 添加h2的配置 设置数据源和密码设置初始化sql语句打开h2的控制台 初始化语句创建一个config表&#xff0c;保存服务配置信息。 完成CRUD接口 controller类 mapper接口 测试 在web控制台可以看到sql已经初始化完成&#xff0c;crud接口…

Postman进阶功能-Mock服务与监控

大家好&#xff0c;前面跟大家分享一些关于 Postman 的进阶功能&#xff0c;当我们深入探索 Postman 的进阶功能时&#xff0c;Mock 服务与监控这两个重要方面便跃然眼前。 首先&#xff0c;Mock 服务为我们提供了一种灵活便捷的方式&#xff0c;让我们在某些实际接口尚未准备好…

Transformer系列专题(二)——multi-headed多头注意力机制

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、什么是multi-headed&#xff08;多头注意力机制&#xff09;二、multi-headed三、multi-headed结果四、堆叠多层总结 前言 在实践中&#xff0c;当给定相同…

四川古力科技抖音小店,创新科技点亮购物新体验

在这个数字化浪潮汹涌的时代&#xff0c;四川古力科技以其前瞻性的战略眼光和创新能力&#xff0c;闪耀于抖音小店这片电商新蓝海&#xff0c;开启了未来购物的新纪元。作为一家集技术研发、产品创新、市场营销于一体的科技型企业&#xff0c;古力科技不仅为消费者带来了前所未…

Android Studio 与 Gradle 及插件版本兼容性

Android Studio 开始新项目时&#xff0c;会自动创建其中部分文件&#xff0c;并为其填充合理的默认值。 项目文件结构布局&#xff1a; 一、Android Gradle 及插件作用&#xff1a; Android Studio 构建系统以 Gradle 为基础&#xff0c;并且 Android Gradle 插件 (AGP) 添加…

游戏行业 2024 Q1报告 | 国内同比上升7.6%,海外收入同比环比双增长,码住!

作为中国音像与数字出版协会主管的中国游戏产业研究院的战略合作伙伴&#xff0c;伽马数据发布了《2024年1—3月中国游戏产业季度报告》。 数据显示&#xff0c; 2024年1—3月&#xff0c;中国游戏市场实际销售收入726.38亿元&#xff0c;同比增长7.60%&#xff0c;主要受移动游…

WXML模板语法-数据绑定

1.数据绑定的基本原则 (1)在data中定义数据 (2)在WXML中使用数据 2.在data页面中定义数据&#xff1a;在页面对应的.js文件中&#xff0c;把数据定义在data对象中即可 &#xff08;这里打错了 应该是数组类型的数据... 报意思啊&#xff09; 3.Mustache语法的格式 把data中的…

Element Plus/vue3 无限级导航实现

在使用element plus 时&#xff0c;最初要使用的就是导航组件了&#xff0c;官网上看到的也就是写死的一级/二级导航&#xff0c;那么如何设计一个无限级且动态的导航呢&#xff1f;毋庸置疑&#xff0c;递归。废话不多说&#xff0c;直接看代码和效果&#xff1a; 代码&#x…

单链表oj

练习 1. 删除val节点 oj链接 这道题最先想出来的方法肯定是在遍历链表的同时删除等于val的节点&#xff0c;我们用第二中思路:不等于val的节点尾插&#xff0c;让后返回新节点。代码如下&#xff1a; struct ListNode* removeElements(struct ListNode* head, int val) {str…

设置height:100%不生效的原因

之前网课案例总是不屑于去看&#xff0c;因为总觉得太花时间&#xff0c;但是不可否认的是&#xff0c;认真去看还是会有收获的&#xff0c;而且常有意外收获 昨天在看实现动画效果的综合案例中&#xff0c;意外解决了我长久以来的一个疑问&#xff1a;为什么给元素设置height…

MyBatis入门——MyBatis XML配置文件(3)

目录 一、配置连接字符串和MyBatis 二、写持久层代码 1、添加 mapper 接口 2、添加 USerInfoXmlMapper.xml 3、测试类代码 三、增删改查操作 1、增&#xff08;Insert&#xff09; 返回自增 id 2、删&#xff08;Delete&#xff09; 3、改&#xff08;update&#xf…

【Linux】-Tomcat安装部署[12]

目录 简介 安装 安装部署JDK环境 解压并安装Tomcat 简介 Tomcat是由Apache开发的一个Servlet容器&#xff0c;实现了对Servlet和JSP的支持&#xff0c;并提供了作为Web服务器的一些特有功能&#xff0c;如Tomcat管理和控制平台、安全域管理和Tomcat阀等。 简单来说&#…

嵌入式学习——3——IO分类模型

1、阻塞IO和非阻塞IO 1.1 阻塞IO - 在阻塞IO模型中&#xff0c;当一个IO操作&#xff08;如读取或写入&#xff09;开始时&#xff0c;如果数据没有准备好&#xff0c;程序会被挂起&#xff08;即阻塞&#xff09;&#xff0c;直到数据准备好并且IO操作完成。 - 在数据准备阶段…

sql server【 特定分隔符隔开的字符串转表】和【 列转逗号隔开的字符串】

文章目录 引言I 特定分隔符隔开的字符串转表II Sql Server 列转逗号隔开的字符串2.1 多列转行,逗号分隔(字段拼接/字段分割)2.1 案例引言 Sql Server 列转逗号隔开的字符串 和 逆转,常用于数据导出和数据查询。 I 特定分隔符隔开的字符串转表 CREATE FUNCTION [dbo].[GetIDLi…

LitCTF

[LitCTF 2023]enbase64 base 64 里面有一个换表的函数 写代码 #include<stdio.h> #include<string.h> #include<stdlib.h> int main() {char *result; char Destination[65]; int v3[65];int j;int i; char Source[]"ABCDEFGHIJKLMNOPQRSTUVWXYZabcde…

【配置】雷池WAF社区版安装

官方文档点击跳转 什么是雷池 雷池&#xff08;SafeLine&#xff09;是长亭科技耗时近 10 年倾情打造的 WAF&#xff0c;核心检测能力由智能语义分析算法驱动。 什么是 WAF WAF 是 Web Application Firewall 的缩写&#xff0c;也被称为 Web 应用防火墙。 区别于传统防火墙…

MySql--SQL语言

目录 SQl---DDL 结构定义 创建、删除 数据库 代码 运行 设计表 数据类型 整数 浮点数 主键 约束 主键自增长 默认值 字段注释 创建、删除 表 代码 运行 代码 代码 运行 SQL---DML 数据操纵 插入数据 代码 运行 代码 运行 代码 运行 代码 …

sqlserver查看索引碎片,并整理

DBCC SHOWCONTIG WITH ALL_INDEXES --查看所有表的索引碎片情况 DBCC SHOWCONTIG(fq_viewvform) --指定表索引碎片情况 dbcc dbreindex(fq_viewvform) --重建表索引 DBCC SHOWCONTIG(fq_viewvform) --检查重建后表索引碎片情况 查看全库索引碎片情况&#xff1a; 查看单表索引…

H800基础能力测试

H800基础能力测试 参考链接A100、A800、H100、H800差异H100详细规格H100 TensorCore FP16 理论算力计算公式锁频安装依赖pytorch FP16算力测试cublas FP16算力测试运行cuda-samples 本文记录了H800基础测试步骤及测试结果 参考链接 NVIDIA H100 Tensor Core GPU Architecture…

中国医学健康管理数字化发展风向标——专家共话未来趋势

随着科技的飞速发展&#xff0c;数字化已经成为中国医学健康管理领域的重要发展方向。 2024年5月20日由中国管理科学研究院智联网研究所、中国民族医药协会医养教育委员会、国家卫健委基层健康服务站、中国老龄事业发展基金会、中国智联网健康管理系统平台、中国医学健康管理数…