杨行网站建设/友情链接出售网

杨行网站建设,友情链接出售网,网站建设与管理清考作业,湘西网站建设〇、上位机,分层架构 界面层 要实现的功能: 展示数据 获取数据 发送数据 数据层 要实现的功能: 转换数据 打包数据 存取数据 通信层 要实现的功能: 打开连接 关闭连接 读取数据 写入数据 实体类 作用: 封装数据…

〇、上位机,分层架构

界面层

要实现的功能:
展示数据
获取数据
发送数据

数据层

要实现的功能:
转换数据
打包数据
存取数据

通信层

要实现的功能:
打开连接
关闭连接
读取数据
写入数据

实体类

作用:
封装数据、传递数据

工具类

一、通信介绍及简单测试

一、PLC (Programmable Logic Controller | 可编程逻辑控制器)

简介:

PLC的英文全称是"Programmable Logic Controller",中文称为“可编程逻辑控制器”。这是一种数字运算操作电子系统,专为在工业环境下应用而设计。它采用可编程存储器,用来在其内部存储执行逻辑运算、顺序控制、定时、计数和算术运算等操作的指令,并通过数字式或模拟式的输入和输出,控制各种类型的机械或生产过程。

3

1、操作:西门子 smart2000 ,使用工具进行通讯

VD 4byte
VW 2byte
VB 1byte
在这里插入图片描述

在这里插入图片描述
V102.0 读一1bit
VB102 读1byte
VW102 读2byte
VD102 读4byte

二、Modbus

Modbus是一种通信协议,主要用于工业电子设备之间进行数据交换。

通讯的模型:
在这里插入图片描述

1、模拟测试(TCP)

所需软件:
mbpoll.exe
mbslave.exe

在这里插入图片描述

激活码:

注册码 对 7和 6 都可以使用

poll 注册码

5A5742575C5D10

slave 注册码

5455415451475662

建立 slave,即服务端 (poll,客户端也是类似的)

进行连接 :
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
设置连接信息
在这里插入图片描述

收发信息的具体情况:

在这里插入图片描述
在这里插入图片描述

1-2、模拟测试(串口)

所需软件:
在这里插入图片描述
在这里插入图片描述
创建虚拟串口对:

在这里插入图片描述
建立 主站 poll
在这里插入图片描述
在这里插入图片描述

建立从站 slave
在这里插入图片描述

在这里插入图片描述

2、存储区、存储区代码、范围

在这里插入图片描述
注:在这里布尔和线圈是一个意思:即一位的数据
在这里插入图片描述
注:一个区的空间为: 65536 每个为 2byte 大(short)

3、关于读写的功能码

在这里插入图片描述

4、协议分类

在这里插入图片描述
注:ModbusASCII因为速度慢,很少被使用
ModbusRTU、ModbusASCII 一般用串口
ModbusTCP 一般用以太网

5、ModbusRTU协议:

在这里插入图片描述

举个例子:
在这里插入图片描述

6、ModbusTCP

在这里插入图片描述
在这里插入图片描述
注:Tx的最后4个字节:00 00 00 02,00 00 表示起始 , 而 00 02 表示读两个字节

三、串口

简介:

一位一位的发送数据(以协上好的频率(波特率)和格式)

格式:
在这里插入图片描述

9针 串口:
在这里插入图片描述

分类:
RS-232
短距离通信

RS-422
长距离通信

RS-485
折中,
通常在半双工的模式下工作
RS-485标准理论上支持长达1200米的传输距离

单工: 类似,广播
半双工: 类似,对讲机
全双工: 类似,电话

测试:虚拟串口

二、C# 通信库的使用

1、s7通信库

1、举例:写一个C#与s7的通信

(1)、所需软件:

S7-PLCSIM Advanced V.30
TIA Portal V17

VD 4byte
VW 2byte
VB 1byte

(2)、界面:

在这里插入图片描述

(3)、添加所需库:

S7netplus
thinger.DataConvertLib
在这里插入图片描述

在这里插入图片描述

(4)、代码:
<1>.简单 测试下 连接-读写
using S7.Net;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace WindowsFormsApp1
{public partial class Form1 : Form{public Form1(){InitializeComponent();Test();}Plc plc = null;private void Test(){plc = new Plc(CpuType.S7200Smart, "192.168.2.1", 0, 0);plc.Open();//读取数据object data = plc.Read("M20.0");this.label1.Text = data.ToString();//写入数据plc.Write("M20.0", false);//不支持V区直接操作,需要映射成DB1plc.Write("DB1.DBX2000.0", true);plc.Close();}}
}
<2>.简单 的封装下
using S7.Net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace WindowsFormsApp1
{public class S7NetLib{private Plc s7netlib = null;    //字段//属性public CpuType CPUType { get;set; }public string IPAddress { get; set; }public short Rack { get; set; }public short Slot { get; set; }//构造函数,初始化连接 所需的变量public S7NetLib(CpuType cpuType,string ip,short rack,short slot){this.CPUType = cpuType;this.IPAddress = ip;this.Rack = rack;this.Slot = slot;}/// <summary>/// 打开PLC连接/// </summary>public void OpenPLC(){if(this.s7netlib == null){s7netlib = new Plc(CPUType,IPAddress,Rack,Slot);}if (!this.s7netlib.IsConnected){s7netlib.ReadTimeout = 1000;//设置超时时间s7netlib.WriteTimeout = 1000;s7netlib.Open();//建立连接}}/// <summary>/// 关闭PLC连接/// </summary>public void ClosePLC(){if(null != this.s7netlib && this.s7netlib.IsConnected){this.s7netlib.Close();}}/// <summary>/// 给plc单个变量写入数据/// </summary>/// <param name="varAddress">写到那里去</param>/// <param name="varValue">写入的值</param>public void WriteDataToPLC(string varAddress, object varValue){OpenPLC();lock (this){this.s7netlib.Write(varAddress, varValue);}}/// <summary>/// 读取一段数据/// </summary>/// <param name="dataType">存储区类型</param>/// <param name="db">DB号</param>/// <param name="startByteAdr">开始字节地址</param>/// <param name="count">字节数量</param>/// <returns>字节数组</returns>public byte[] ReadDataFromPLC(DataType dataType,int db,int startByteAdr,int count){lock (this){byte[] bytes = this.s7netlib.ReadBytes(dataType,db,startByteAdr,count);return bytes;}}}
}
using S7.Net;
using System.Windows.Forms;namespace WindowsFormsApp1
{public partial class Form1 : Form{public Form1(){InitializeComponent();Test();}private void Test(){S7NetLib plc = new S7NetLib(CpuType.S7200, "192.168.2.1", 0, 0);plc.WriteDataToPLC("M2.2", true);byte[] dataBytes = null;dataBytes = plc.ReadDataFromPLC(DataType.DataBlock, 1, 0, 10);}}
}

一次读一个PDU 的长度,不同 CPU的 PDU 的长度不同
在这里插入图片描述

2、C# + SQLSERVER

〇、环境

软件的安装(服务器端、客户端)

服务器端:
SQL Sever 下载地址:
https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

客户端
在这里插入图片描述

服务器端的操作:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

客户端的操作:

在这里插入图片描述
在这里插入图片描述

两种连接方式:
在这里插入图片描述

SQL Server 的连接配置(增加使用密码登录的用户):

第一步:
在这里插入图片描述
在这里插入图片描述
第二步:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
第三步: 重新启动,在连接登录
在这里插入图片描述.

开启远程用户登录的方式(使用 IP 和 端口号)

第一步:
在这里插入图片描述

在这里插入图片描述

第二步:
在这里插入图片描述
第三步:重启服务
右键我的电脑,点击属性
在这里插入图片描述

第四步:最后登录
在这里插入图片描述

一、操作软件:

SQL Server Management Studio

在这里插入图片描述

1、两种连接方式:

在这里插入图片描述

2、新建表

在这里插入图片描述
在这里插入图片描述
然后 ctrl+s 保存

3、添加数据

在这里插入图片描述

4、查询数据

在这里插入图片描述
注:注释是在前面加 –
在这里插入图片描述

5、解决不允许保存的弹窗

在这里插入图片描述

6、设置主键

在这里插入图片描述

7、更改数据(增加、删除、需改)
  --查select * from UserT--存--新增insert into UserT(UserName,Password,NickName) values('111','222','333')--删除delete from UserT where UserName='111'delete from UserT where UserName='111' and Password='888'--修改update UserT set UserName='a' where UserName='111'

到某个指定的数据库

use QingTongXiaWaterPlant_test
go

修改某一段名的数据类型:

use QingTongXiaWaterPlant_test
go
alter table dbo.WaterFlowData alter column d17 float null;

二、数据库数据类型

在这里插入图片描述

三、数据库的约束

在这里插入图片描述

四、运算符:

=

五、SQL 语句

(1)、搜索当前存在哪些数据库:
select * from sysdatabases
(2)、创建数据库:

1、创建数据库所在的文件夹
在这里插入图片描述
建好的文件
在这里插入图片描述

2、执行 sql语句

use master
go
if exists(select * from sysdatabases where name='MISDB') --如果原来存在这个数据库,则进行删除
drop database MISDB
go
--创建数据库
create database MISDB
on primary
(name='MISDB_MData',--必须唯一filename='D:\DB\MISDB_MData.mdf', --物理文件名,主存储文件size=30MB,filegrowth=10MB
)
,
(name='MISDB_nData',filename='D:\DB\DBMISDB_nData.ndf',  --次存储文件size=20MB,filegrowth=10MB
)
log on
(name='MISDB_log1',filename='D:\DB\MISDB_log1.ldf',	--日志文件size=20MB,filegrowth=10MB
)
,
(name='MISDB_log2',filename='D:\DB\MISDB_log2.ldf',		--日志文件size=20MB,filegrowth=10MB
)
(3)、创建表:
--创建数据表,是在指定的数据库里面
use MISDB
go
if exists(select * from sysobjects where name='Department')	  --如果已经有了 Department 表则对其进行删除
drop table Department
go
create table Department
(DepartmentId int identity(10,1)primary key,--部门字段值,由系统自动生成,从10开始,每次增加1  primary key 是主键的标识DepartmentName varchar(50)not null
)
go
if exists(select * from sysobjects where name='Post')		--如果已经有了 Post 表则对其进行删除
drop table Post
go
create table Post
(PostId int identity(10,1)primary key,PostName varchar(50) not null
)
go
if exists(select * from sysobjects where name='Employee')
drop table Employee
go
create table Employee
(EmplyeeId int identity(100,1) primary key,EmplyeeName varchar(50) not null,Gender char(2) not null check(Gender='男' or Gender='女'),NowAddress nvarchar(100) default('地址不详'),IdNo char(18) not null check(len(Idno)=18),--检查约束WeiXinNumber varchar(20)not null,PhoneNumber varchar(50) not null,OtherWork nvarchar(50) not null,EntryDate datetime not null,PostId int references Post(PostId),                    --外键引用DepartmentId int references Department(DepartmentId)   --外键引用
)
go
(4)、简单的 增、删、改、查
  --查select * from UserT--存--新增insert into UserT(UserName,Password,NickName) values('111','222','333')--删除delete from UserT where UserName='111'delete from UserT where UserName='111' and Password='888'--修改update UserT set UserName='a' where UserName='111'

到某个指定的数据库

use QingTongXiaWaterPlant_test
go

修改某一段名的数据类型:

use QingTongXiaWaterPlant_test
go
alter table dbo.WaterFlowData alter column d17 float null;
(5)、增加
use MISDB
go
select * from Department
select * from Post
select * from Employeeinsert into Department(DepartmentName)
values('开发部'),('测试部'),('财务部'),('人事部')
inSert into Post(PostName)
values('软件工程师'),('测试工程师'),('实施工程师'),('财务经理'),('人事经理')
insert into Employee(EmployeeName,Gender,NowAddress,IdNo,
WeiXinNumber,PhoneNumber,OtherWork,EntryDate,PostId,DepartmentId)values
('Kiter10','男','天津','123456789123456789','tt00','36954215478','没有','2024-09-09',10,12),
('Kiter11','男','北京','123456789123456789','tt00','36954215478','没有','2024-09-09',10,12),
('Kiter12','男','福州','123456789123456789','tt00','36954215478','没有','2024-09-09',10,12),
('Kiter13','男','西安','123456789123456789','tt00','36954215478','没有','2024-09-09',10,12),
('Kiter14','男','苏州','123456789123456789','tt00','36954215478','没有','2024-09-09',10,12),
('Kiter15','男','咸阳','123456789123456789','tt00','36954215478','没有','2024-09-09',10,12),
('Kiter16','男','永寿','123456789123456789','tt00','36954215478','没有','2024-09-09',10,12),
('Kiter17','女','天津','123456789123456789','tt00','36954215478','没有','2024-09-09',10,12),
('Kiter18','男','天津','123456789123456789','tt00','36954215478','没有','2024-09-09',10,12),
('Kiter19','男','天津','123456789123456789','tt00','36954215478','没有','2024-09-09',10,12),
('Kiter20','男','天津','123456789123456789','tt00','36954215478','没有','2024-09-09',10,12),
('Kiter21','女','天津','123456789123456789','tt00','36954215478','没有','2024-09-09',10,12),
('Kiter22','男','天津','123456789123456789','tt00','36954215478','没有','2024-09-09',10,12),
('Kiter23','男','天津','123456789123456789','tt00','36954215478','没有','2024-09-09',10,12),
('Kiter24','男','天津','123456789123456789','tt00','36954215478','没有','2024-09-09',10,12),
('Kiter25','女','天津','123456789123456789','tt00','36954215478','没有','2024-09-09',10,12),
('Kiter26','男','天津','123456789123456789','tt00','36954215478','没有','2024-09-09',10,12),
('Kiter27','男','天津','123456789123456789','tt00','36954215478','没有','2024-09-09',10,12)
(6)、删除
delete from Employee where EmployId=112
delete from Employee where EmployId>=117
(7)、修改
update Employee set EmployeeName='小王',NowAddress='天津X'where EmployId=101
(8)、查询(及内查询)
select * from Department
select * from Post
select * from employee--条件查询
select EmployId,EmployeeName,Gender,NowAddress,PhoneNumber
from Employee where EmployId>=105 and EmployId<=115 and gender='女'update Employee set EmployeeName='小王',NowAddress='天津X'where EmployId=101
delete from Employee where EmployId=112
delete from Employee where EmployId>=117--内连接查询
select EmployId,EmployeeName,PhoneNumber,Post.PostId,Post.PostName
from Employee
inner join Post on Post.PostId=Employee.PostId--内连接查询
select EmployId,EmployeeName,PhoneNumber,
Post.PostId,PostName,DepartmentName
from Employee
inner join Post on Post.PostId=Employee.PostId
inner join Department on Department.DepartmentId=Employee.DepartmentId--聚合查询
select count(*) as 员工总数 from Employee
select 编号平均数=avg(EmployId)from Employee
select 编号最小值=min(EmployId)from Employee
select 编号最大值=max(EmployId)from Employee
(9)、给表增加列:
ALTER TABLE Employees
ADD Column1 INT,Column2 NVARCHAR(50),Column3 DATETIME;    
(10)、存储过程:

新建

CREATE PROCEDURE JiaYao-- 输入参数 执行哪个加药@Index varchar(32) ='',@C1_DangLiang real=0,-- 输出@dosage real output
AS
BEGIN-- 为了不返回 每条sql 影响多少条记录的信息SET NOCOUNT ON select avg(data_js_d1)   as js_cod,from RealDataif @Index='PAC1'begin	set @dosage =js_cod/3;endif @Index='PAC2'begin	set @dosage =js_cod/2;endEND 

修改

ALTER PROCEDURE JiaYao-- 输入参数 执行哪个加药@Index varchar(32) ='',@C1_DangLiang real=0,-- 输出@dosage real output
AS
BEGIN-- 为了不返回 每条sql 影响多少条记录的信息SET NOCOUNT ON select avg(data_js_d1)   as js_cod,from RealDataif @Index='PAC1'begin	set @dosage =js_cod/3;endif @Index='PAC2'begin	set @dosage =js_cod/2;endEND 

执行的sql


DECLARE @dosage real;EXEC JiaYao @dosage=1.3,-- 输入参数 执行哪个加药@Index ='PAC1',

六、在C#中 使用,SQLServer 数据库

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Management.Instrumentation;namespace ConsoleApp1
{public class SqlServer{/**         建立连接所需要的信息* Server   是服务器的地址* DataBase 是数据库的名称* Uid      是登录的用户名* Pwd      是用户名的密码*///private string connString1 = "Server=E2JMKGABJ62SR4X\\SQLEXPRESS;DataBase=MISDB;Uid=sa;Pwd=123456";//private string connString1 = "Server=192.168.31.130,1433\\SQLEXPRESS;DataBase=MISDB;Uid=sa;Pwd=123456";private string connString1 = "Server=192.168.31.130,1433;DataBase=MISDB;Uid=sa;Pwd=123456";//建立连接的方法public void ConnectDB(){SqlConnection conn = new SqlConnection(connString1);conn.Open();if (conn.State == System.Data.ConnectionState.Open){Console.WriteLine("连接成功");}conn.Close();if (ConnectionState.Closed == conn.State){Console.WriteLine("连接关闭");}}//插入语句的写法public void Insert(){//创建建立连接的对象 -- SqlConnectionSqlConnection conn = new SqlConnection(connString1);//sql语句,string sql = "insert into Employee(EmployeeName,Gender,NowAddress,IdNo,WeiXinNumber,PhoneNumber,OtherWork,EntryDate,PostId,DepartmentId)Values('Kiter30','女','天津','123456789123456789','uio001','96587112365','没有的','2024-10-06',10,12)";//创建执行 sql 语句的对象SqlCommand cmd = new SqlCommand(sql, conn);//连接conn.Open();//执行sql语句int result = cmd.ExecuteNonQuery();//断开连接conn.Close();Console.WriteLine("受影响的行数:"+result);}//变更数据的写法public void Update(){//创建建立连接的对象 -- SqlConnectionSqlConnection conn = new SqlConnection(connString1);//sql语句string sql = "update Employee set EmployeeName='UBM'where EmployId=121";//创建执行 sql 语句的对象SqlCommand cmd = new SqlCommand(sql, conn);//连接conn.Open();//执行sql语句int result = cmd.ExecuteNonQuery();//断开连接conn.Close();Console.WriteLine("受影响的行数:" + result);}//删除表中的记录public void Delete(){//创建建立连接的对象 -- SqlConnectionSqlConnection conn = new SqlConnection(connString1);//要执行的 sql 语句string sql = "delete from Employee where EmployId=102";//实例化 要执行 sql的对象 -- SqlCommandSqlCommand cmd = new SqlCommand(sql, conn);//建立连接conn.Open();//执行 sql语句int result = cmd.ExecuteNonQuery();//关闭练级conn.Close();Console.WriteLine("受影响的行数:" + result);}//执行查询结果为1个的 sql 语句public void GetSingleResult(){//创建建立连接的对象 -- SqlConnectionSqlConnection conn = new SqlConnection(connString1);//要执行的 sql 语句string sql = "select EmployeeName from Employee where EmployId=101";//实例化 要执行 sql的对象 -- SqlCommandSqlCommand cmd = new SqlCommand(sql, conn);//建立连接conn.Open();//执行 sql语句  ExecuteScalar 是执行只有一个返回结果的sql 语句object result = cmd.ExecuteScalar();//关闭连接conn.Close();Console.WriteLine(result);}//执行查询结果为1个的 sql 语句public void GetSingleResult2(){//创建建立连接的对象 -- SqlConnectionSqlConnection conn = new SqlConnection(connString1);//要执行的 sql 语句string sql = "select 员工总数=count(*)from Employee";//实例化 要执行 sql的对象 -- SqlCommandSqlCommand cmd = new SqlCommand(sql, conn);//建立连接conn.Open();//执行 sql语句  ExecuteScalar 是执行只有一个返回结果的sql 语句object result = cmd.ExecuteScalar();int count = (int)result;//如果程序需要使用具体数据类型,就可以转换//关闭连接conn.Close();Console.WriteLine(count);}//用 ExecuteScalar 来执行 插入操作,返回看新增的记录是第几条的public void GetSingleResult3(){SqlConnection conn = new SqlConnection(connString1);string sql = "insert into Employee(EmployeeName,Gender," +"NowAddress,IdNo,WeiXinNumber,PhoneNumber,OtherWork," +"EntryDate,PostId,DepartmentId)"+"Values('Kiter50','男','北京','123456789123456789','qwer1','96325451784','没有','2024-11-07',10,12)";sql += ";select @@Identity";SqlCommand cmd = new SqlCommand (sql,conn);conn.Open();int result = Convert.ToInt32(cmd.ExecuteScalar());conn.Close();Console.WriteLine("编号:"+result);}//读取多条记录 (查询的 多个表)public void GetReaderList(){//创建建立连接的对象 -- SqlConnectionSqlConnection conn = new SqlConnection(connString1);//要执行的 sql 语句string sql = "select EmployeeName,Gender,NowAddress from Employee";//实例化 要执行 sql的对象 -- SqlCommandSqlCommand cmd = new SqlCommand(sql, conn);//建立连接conn.Open();//执行结果集查询SqlDataReader reader = cmd.ExecuteReader();//逐行读取while (reader.Read()){string result = reader["EmployeeName"].ToString() + reader["Gender"] + reader["NowAddress"];Console.WriteLine(result);}//释放资源reader.Close(); //关闭读取器conn.Close();   //关闭连接}//读取多条记录(查询的是多个表)public void GetReaderList2(){//创建建立连接的对象 -- SqlConnectionSqlConnection conn = new SqlConnection(connString1);//要执行的 sql 语句string sql = "select EmployeeName,Gender,NowAddress from Employee";sql += ";select DepartmentId,DepartmentName from Department";//实例化 要执行 sql的对象 -- SqlCommandSqlCommand cmd = new SqlCommand(sql, conn);//建立连接conn.Open();//执行结果集查询SqlDataReader reader = cmd.ExecuteReader();//逐行读取while (reader.Read()){string result = reader["EmployeeName"].ToString()+"\t"+reader[1]+"\t"+reader["NowAddress"];Console.WriteLine(result);}Console.WriteLine("*************");if (reader.NextResult()){while (reader.Read()){Console.WriteLine($"{reader["DepartmentId"]}\t{reader["DepartmentName"]}");}}//关闭读取器reader.Close();//关闭连接conn.Close();}//使用 DataSet 和 SqlDataAdapter 读取多条记录public void GetDataSet1(){//创建连接对象SqlConnection conn = new SqlConnection(connString1);//sql 语句string sql = "select EmployeeName,Gender,NowAddress from Employee";//创建执行sql的对象SqlCommand cmd = new SqlCommand(sql, conn);//打开连接conn.Open();//创建数据适配器对象SqlDataAdapter da = new SqlDataAdapter(cmd);//创建一个数据集对象DataSet ds = new DataSet();//将查询到到结果填入到,内存中(DataSet)da.Fill(ds);//关闭连接conn.Close();//读取数据DataTable dt = ds.Tables[0];foreach(DataRow dr in dt.Rows){Console.WriteLine($"{dr["EmployeeName"]}\t{dr["Gender"]}\t{dr["NowAddress"]}");}}//使用 DataSet 和 SqlDataAdapter 读取多条记录(查询的是多个表)public void GetDataSet2(){//创建连接对象SqlConnection conn = new SqlConnection(connString1);//sql 语句string sql = "select EmployeeName,Gender,NowAddress from Employee";//创建执行sql的对象SqlCommand cmd = new SqlCommand(sql, conn);//打开连接conn.Open();//创建数据适配器对象SqlDataAdapter da = new SqlDataAdapter(cmd);//创建一个数据集对象DataSet ds = new DataSet();//填充数据da.Fill(ds,"Employee");cmd.CommandText = "select DepartmentId,DepartmentName from Department";da.Fill(ds, "Department");//关闭连接conn.Close();//读取数据DataTable dt = ds.Tables["Employee"];foreach(DataRow dr in dt.Rows){Console.WriteLine($"{dr["EmployeeName"]}\t{dr["Gender"]}\t{dr["NowAddress"]}");}Console.WriteLine("........................");foreach(DataRow dr in ds.Tables["Department"].Rows){Console.WriteLine($"{dr["DepartmentId"]}\t{dr["DepartmentName"]}");}}//写带 参数的SQL 语句public void GetReaderList5(){//创建建立连接的对象 -- SqlConnectionSqlConnection conn = new SqlConnection(connString1);//要执行的 sql 语句string sql = "select EmployeeName,Gender,NowAddress from Employee where EmployId > @Number";SqlParameter[] param = new SqlParameter[]{new SqlParameter("@Number",106)};//实例化 要执行 sql的对象 -- SqlCommandSqlCommand cmd = new SqlCommand(sql, conn);//添加参数cmd.Parameters.AddRange(param);//建立连接conn.Open();//执行结果集查询SqlDataReader reader = cmd.ExecuteReader();//逐行读取while (reader.Read()){string result = reader["EmployeeName"].ToString() + "\t" + reader[1] + "\t" + reader["NowAddress"];Console.WriteLine(result);}//关闭读取器reader.Close();//关闭连接conn.Close();}}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace ConsoleApp1
{internal class Program{static void Main(string[] args){SqlServer sqlServer = new SqlServer();//建立连接,然后断开//sqlServer.ConnectDB();//插入新的行//sqlServer.Insert();//修改数据库中的信息//sqlServer.Update();//删除数据库中的记录//sqlServer.Delete();//执行只返回一个结果的 sql 语句//sqlServer.GetSingleResult();//执行只返回一个结果的 sql 语句//sqlServer.GetSingleResult2();//用 ExecuteScalar 来执行 插入操作,返回看新增的记录是第几条的//sqlServer.GetSingleResult3();//读取多条记录//sqlServer.GetReaderList();//读取多个表的多条记录//sqlServer.GetReaderList2();//使用 SqlDataAdapter 和 DataSet 读取数据//sqlServer.GetDataSet1();//使用 SqlDataAdapter 和 DataSet 读取多个表的数据//sqlServer.GetDataSet2();//使用带参的sql语句sqlServer.GetReaderList5();Console.ReadLine();}}
}

查询

在这里插入图片描述
通过关闭 SqlDataReader,来关闭 SqlConnection
在这里插入图片描述

七、SqlHelper

先安装库:
在这里插入图片描述

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Configuration;
using System.Web;
//using System.Data.SqlClient;
using System.Data;
using Microsoft.SqlServer.Server;using Microsoft.Data.SqlClient;
using System.Configuration;namespace ToolsLib
{public class SqlServerHelper{//用于连接数据库的字符串//private static string ConnString { get; set; } = ConfigurationManager.ConnectionStrings["connString1"].ToString();private static string ConnString { get; set; } = ConfigurationManager.AppSettings["connString1"];/// <summary>/// 执行 insert\update\delete 类型的 sql 语句/// </summary>/// <param name="cmdText">sql语句或存储过程名称</param>/// <param name="paramArray">参数数组</param>/// <returns>受影响的行数</returns>/// <exception cref="Exception"></exception>public static int ExecuteNonQuery(string cmdText, SqlParameter[] paramArray = null){SqlConnection conn = new SqlConnection(ConnString);SqlCommand cmd = new SqlCommand(cmdText, conn);if (paramArray != null){cmd.Parameters.AddRange(paramArray);}try{conn.Open();return cmd.ExecuteNonQuery();//执行}catch (Exception ex){//可以在这个地方写入日志(log文件)string errorMsg = $"{DateTime.Now}:执行public static int ExecuteNonQuery(sting cmdText,SqlParameter[]para---{ex.Message}";throw new Exception(errorMsg);}finally{conn.Close();}}/// <summary>/// 执行查询语句,查询结果是但是一个结果/// </summary>/// <param name="cmdText"></param>/// <param name="paramArray"></param>/// <returns></returns>/// <exception cref="Exception"></exception>public static object ExecuteScalar(string cmdText, SqlParameter[] paramArray = null){SqlConnection conn = new SqlConnection(ConnString);SqlCommand cmd = new SqlCommand(cmdText, conn);if (paramArray != null){cmd.Parameters.AddRange(paramArray);}try{conn.Open();return cmd.ExecuteScalar();}catch (Exception ex){throw new Exception("执行public staticobjectExecute Scalar(string cmdText,SqlParameter[] paramArray = null)异常" + ex.Message);}finally{conn.Close();//关闭连接}}/// <summary>/// 执行查询语句/// </summary>/// <param name="cmdText"></param>/// <param name="paramArray"></param>/// <returns></returns>/// <exception cref="Exception"></exception>public static SqlDataReader ExecuteReader(string cmdText, SqlParameter[] paramArray = null){SqlConnection conn = new SqlConnection(ConnString);SqlCommand cmd = new SqlCommand(cmdText, conn);if (paramArray != null){cmd.Parameters.AddRange(paramArray);}try{conn.Open();//这里返回的 SqlDataReader 是用来进行进一步查询的,//这里的 加的入参是:CommandBehavior.CloseConnection  为了,关闭 SqlDataReader后来自动关闭 conn连接 做设置//因为 SqlDataReader 是需要在外部进行访问的return cmd.ExecuteReader(CommandBehavior.CloseConnection);//执行}catch (Exception ex){throw new Exception($"执行public staticobjectExecute Scalar(stringcmdText,SqlParameter[] paramArray=null) ---{ex.Message}");}}/// <summary>/// 返回包含一张数据表的数据集的查询/// </summary>/// <param name="sql"></param>/// <param name="tableName"></param>/// <returns></returns>/// <exception cref="Exception"></exception>public static DataSet GetDataSet(string sql, string tableName = null){SqlConnection conn = new SqlConnection(ConnString);SqlCommand cmd = new SqlCommand(sql, conn);SqlDataAdapter da = new SqlDataAdapter(cmd);DataSet ds = new DataSet();try{conn.Open();if (tableName == null){da.Fill(ds);}else{da.Fill(ds, tableName);}return ds;}catch (Exception ex){throw new Exception($"执行public static DataSet GetDataSet(string sql,string tableName=null)方法出现异常{ex.Message}");}finally{conn.Close();}}public static DataSet GetDataSet(Dictionary<string, string> dicTableAndSql){SqlConnection conn = new SqlConnection(ConnString);SqlCommand cmd = new SqlCommand();cmd.Connection = conn;SqlDataAdapter da = new SqlDataAdapter(cmd);DataSet ds = new DataSet();try{conn.Open();foreach (string tbName in dicTableAndSql.Keys){cmd.CommandText = dicTableAndSql[tbName];da.Fill(ds, tbName);//加入多个表}return ds;}catch (Exception ex){throw new Exception("执行public static DataSet GetDataSet(string ssql,string tableName=null)方法出行异常" + ex.Message);}finally{conn.Close();}}}
}

八、存储过程的写法:

创建

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GOCREATE PROCEDURE TestProcedure@Parameter1 Int =0,@Parameter2 Int output
AS
BEGINSET NOCOUNT ONselect * from UserT;Set @Parameter2 = 999;
END
GO

修改

USE [MyDB]
GO
/****** Object:  StoredProcedure [dbo].[TestProcedure]    Script Date: 12/17/2024 10:08:29 AM ******/
-- 与null比较的结果会被视为 未知,而不是 true 或 false
SET ANSI_NULLS ON
GO
-- 可以使用用双引号,引起来的关键字
SET QUOTED_IDENTIFIER ON
GOALTER PROCEDURE [dbo].[TestProcedure]-- 输入参数@Parameter1 Int =0,-- 输出参数@Parameter2 Int output
AS
BEGIN-- 为了不返回 每条sql 影响多少条记录的信息SET NOCOUNT ONselect * from UserT;Set @Parameter2 = 999;
END

执行

declare @Parameter2 int;exec TestProcedure @Parameter1=20, @Parameter2= @Parameter2 output;select @Parameter2 as Parameter2;

3、NModbus4 通讯库的使用

1、使用串口,封装 NModbus4 库

安装 NModbus4 库:
在这里插入图片描述

封装的代码:

using Modbus.Device;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace WindowsFormsApp1
{/// <summary>/// 基于NModbus4的开源库的二次封装/// </summary>internal class ModbusRTU{#region 串口打开//声明.NET串口对象private SerialPort serialPort;//声明Modbus协议串口主设备对象private ModbusSerialMaster master;//                         COM1          9600               N           8              1             public bool Connect(string portName, int baudRate,Parity parity,int dataBits,StopBits stopBits){if(this.serialPort == null && this.serialPort.IsOpen){this.serialPort.Close();}try{//创建.NET串口对象this.serialPort = new SerialPort(portName,baudRate, parity,dataBits,stopBits);//设置串口的读写超时时间(防止长时间阻塞)this.serialPort.ReadTimeout = 1000;this.serialPort.WriteTimeout = 1000;//打开 .NET 串口this.serialPort.Open();//使用 Modbus串口工厂方法 创建 Modbus串口主设备 对象master = ModbusSerialMaster.CreateRtu(this.serialPort);return true;}catch(Exception ex){//打印异常信息throw new Exception("[串口]打开失败,"+ex.Message);}}#endregion#region 关闭串口public void DisConnect(){if(this.serialPort != null && this.serialPort.IsOpen){//this.serialPort?.Close();this.serialPort.Close();}master = null;}#endregion#region 读取数据/// <summary>/// 【01】功能码:读取输出线圈/// </summary>/// <param name="slaveId">从站地址</param>/// <param name="start">起始线圈地址</param>/// <param name="length">线圈的数量</param>/// <returns>返回bool数组</returns>/// <exception cref="Exception"></exception>public bool[]ReadOutputCoils(byte slaveId,ushort start,ushort length){try{//Coils 线圈的意思return this.master.ReadCoils(slaveId, start, length);}catch(Exception ex){throw new Exception("[读取输出线程]失败" + ex.Message);}}/// <summary>/// [02] 功能码:读取输入线圈/// </summary>/// <param name="slaveId">从站地址</param>/// <param name="start">起始线圈地址</param>/// <param name="length">线圈的数量</param>/// <returns>返回bool数组</returns>/// <exception cref="Exception"></exception>public bool[] ReadInputCoils(byte slaveId, ushort start, ushort length){try{return this.master.ReadInputs(slaveId, start, length);}catch (Exception ex){throw new Exception("[读取输入线圈]失败:" + ex.Message);}}// 一个寄存器是两个 字节的大小/// <summary>/// 【03】 功能码:读取输出寄存器/// </summary>/// <param name="slaveId">从站地址</param>/// <param name="start">起始寄存器地址</param>/// <param name="length">寄存器的数量</param>/// <returns>返回byte数组</returns>/// <exception cref="Exception"></exception>public byte[] ReadHoldingRegister(byte slaveId,ushort start,ushort length){try{//获取数据数组ushort[] data = this.master.ReadHoldingRegisters(slaveId, start, length);// 一个寄存器是两个 字节的大小//把ushort类型数组,转换成List字节数组List<byte> result = new List<byte>();foreach(var item in data){result.AddRange(BitConverter.GetBytes(item));}return result.ToArray();}catch(Exception ex){throw new Exception("[读取输出寄存器]失败," + ex.Message);}}/// <summary>/// [04] 功能码:读取输入寄存器/// </summary>/// <param name="slaveId">从站地址</param>/// <param name="start">起始寄存器地址</param>/// <param name="length">寄存器的数量</param>/// <returns>返回byte数组</returns>/// <exception cref="Exception"></exception>public byte[] ReadInputRegister(byte slaveId,ushort start,ushort length){try{//获取数据数组ushort[] data = this.master.ReadInputRegisters(slaveId, start, length);//把ushort类型的数组,转换成List字节数组List<byte> result = new List<byte>();foreach (var item in data){result.AddRange(BitConverter.GetBytes(item));}return result.ToArray();}catch(Exception ex){throw new Exception("[读取输入寄存器]失败" + ex.Message);}}#endregion#region 写入数据/// <summary>/// [05] 功能码:预置单线圈/// </summary>/// <param name="slaveId">从站地址</param>/// <param name="start">当前线圈地址</param>/// <param name="value">线圈的值</param>/// <returns></returns>/// <exception cref="Exception"></exception>public bool PreSetSingleCoil(byte slaveId,ushort start,bool value){try{this.master.WriteSingleCoil(slaveId, start, value);return true;}catch(Exception ex){throw new Exception("[预置单线圈]失败," + ex.Message);}}/// <summary>/// [06]功能码:预置单寄存器/// </summary>/// <param name="slaveId">从站地址</param>/// <param name="address">寄存器地址</param>/// <param name="value">字节地址(2个字节)</param>/// <returns></returns>/// <exception cref="Exception"></exception>public bool PreSetSingleRegister(byte slaveId,ushort address,byte[] value){try{this.master.WriteSingleRegister(slaveId, address, BitConverter.ToUInt16(value, 0));return true;}catch (Exception ex){throw new Exception("【预置单寄存器】失败," + ex.Message);}}public bool PreSetSingleRegister(byte slaveId,ushort address,short value){return PreSetSingleRegister(slaveId, address, BitConverter.GetBytes(value));}public bool PreSetSingleRegister(byte slaveId,ushort address,ushort value){return PreSetSingleRegister(slaveId, address, BitConverter.GetBytes(value));}/// <summary>/// 【0F】 功能码 预置多个线圈/// </summary>/// <param name="slaveId">从站地址</param>/// <param name="start">线圈开始地址</param>/// <param name="value">布尔数组</param>/// <returns></returns>/// <exception cref="Exception"></exception>public bool PreSetMutiCoils(byte slaveId,ushort start,bool[] value){try{this.master.WriteMultipleCoils(slaveId, start, value);return true;}catch(Exception ex){throw new Exception("[预制多线圈]失败," + ex.Message);}}/// <summary>/// [10] 功能码:预制多个寄存器/// </summary>/// <param name="slaveId">从站地址</param>/// <param name="start">寄存器开始地址</param>/// <param name="values">字节数组</param>/// <returns></returns>/// <exception cref="Exception"></exception>public bool PreSetMultiRegister(byte slaveId,ushort start, byte[] values){//必须是偶数字节// 因为两字节 , 才是也给寄存器的大小if(values == null||values.Length == 0 || values.Length%2 == 1){return false;}//将字节数组转换成ushort数组ushort[] data = new ushort[values.Length / 2];for (int i = 0; i < values.Length; i += 2){data[i] = BitConverter.ToUInt16(values, i);}try{this.master.WriteMultipleRegisters(slaveId, start, data);return true;}catch(Exception ex){throw new Exception("[预制多寄存器]失败,"+ex.Message);}}/// <summary>/// [0F] 功能码:预制多个线圈/// </summary>/// <param name="slaveId">站地址</param>/// <param name="start">线圈开始地址</param>/// <param name="value">布尔数组</param>/// <returns></returns>/// <exception cref="Exception"></exception>public bool PreSetMultiCoils(byte slaveId,ushort start,bool[] value){try{this.master.WriteMultipleCoils(slaveId,start,value);return true;}catch (Exception ex) {throw new Exception("[预制多个线圈]失败" + ex.Message);}}#endregion}
}

三、手写通信库

四、WPF基本使用

0、xaml 的基础操作

xaml是一种声明型语言,一般来讲,一个标签就是一个对象;而一个标签的属性就是一个对象的属性。
给标签属性赋值有三种方式:

1、 Attribute = Value 形式

画一个 长方形

        <Rectangle Width="100" Height="80" Stroke="Black"/>

画一个三角形

        <Path Data="M 0,0 L 200,100 L 100,200 Z" Stroke="Black" Fill="Red"/>
将一个字符串转换成标签(对象)的写法:

在这里插入图片描述
MainWindow.xaml

<Window x:Class="WpfApp1.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:WpfApp1"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800"><Window.Resources><local:Dog x:Key="dog1" Name="Bob1"/><local:Dog x:Key="dog2" Name="Bob2"/><local:Dog x:Key="dog3"  Name="Bob3" Child="123"/></Window.Resources><Grid><Button Content="Hello!" Width="120" Height="30" Click="Button_Click"/></Grid>
</Window>

Dog.cs

using System.ComponentModel;
using System.Globalization;namespace WpfApp1
{//为类添加转换规则[TypeConverterAttribute(typeof(NameToDogTypeConverter))]public class Dog{public string Name { get; set; }public Dog Child { get; set; }}public class NameToDogTypeConverter : TypeConverter{//将字符串转成 Dog 的规则public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value){string name = value.ToString();Dog child = new Dog();child.Name = name;return child;}}
}

MainWindow.xaml.cs

using System.Windows;namespace WpfApp1
{/// <summary>/// MainWindow.xaml 的交互逻辑/// </summary>public partial class MainWindow : Window{public MainWindow(){InitializeComponent();}private void Button_Click(object sender, RoutedEventArgs e){Dog dog =this.FindResource("dog3") as Dog; ;//找到字典资源中 标签对象的方法if(null != dog){//取出标签对象中的属性MessageBox.Show(dog.Name + "/" + dog.Child.Name);}}}
}

另一种等价的添加属性 的方式:

        <Button Content="登录" FontSize="20" Height="50" Width="300"/>
        <Button Content="登录"><Setter Property="Background" Value="Red"/><Setter Property="FontSize" Value="20"/><Setter Property="Height" Value="50"/><Setter Property="Width" Value="300"/></Button>
2、属性标签

形如:
<LinearGradientBrush.StartPoint>
就是属性标签,它不是一个对象,而是对象的属性,用标签的形式来写
例子 1:
在这里插入图片描述

<Window x:Class="WpfApp1.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"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800"><Grid><Rectangle Width="200" Height="160" Stroke="Blue"><Rectangle.Fill><LinearGradientBrush><LinearGradientBrush.StartPoint><Point X="0" Y="0"/></LinearGradientBrush.StartPoint><LinearGradientBrush.EndPoint><Point X="1" Y="1"/></LinearGradientBrush.EndPoint><LinearGradientBrush.GradientStops><GradientStopCollection><GradientStop Offset="0.2" Color="LightBlue"/><GradientStop Offset="0.7" Color="DarkBlue"/><GradientStop Offset="1.0" Color="Blue"/></GradientStopCollection></LinearGradientBrush.GradientStops></LinearGradientBrush></Rectangle.Fill></Rectangle></Grid>
</Window>

例子 2:
在这里插入图片描述

<Window x:Class="WpfApp1.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"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800"><Grid><Button Width="120" Height="30"><Button.Content><Rectangle Width="20" Height="20" Stroke="DarkGreen" Fill="LawnGreen"/></Button.Content></Button></Grid>
</Window>
3、标签扩展

在这里插入图片描述

1、创建一个项目

在这里插入图片描述

程序入口:
在这里插入图片描述

默认入口点:WPF 应用程序的默认入口点是 App.xaml 和 App.xaml.cs 文件。在这些文件中定义了应用程序的启动逻辑和主窗口。
自定义入口点:如果需要,可以在代码中定义一个 Main 方法并在其中创建和运行 Application 对象,但这不是必需的,除非你有特定的初始化需求。

手写函数函数入口(一般不需要):

// Entry point defined in a custom Main method (if needed)
public static class Program
{[STAThread]public static void Main(){var app = new App();app.InitializeComponent();app.Run();}
}
// App.xaml.cs
using System.Windows;namespace MyWpfApp
{public partial class App : Application{// Application startup logic can be placed hereprotected override void OnStartup(StartupEventArgs e){base.OnStartup(e);// Custom startup logic (if needed)}protected override void OnExit(ExitEventArgs e){base.OnExit(e);// Custom exit logic (if needed)}}
}

窗体 xaml 文件的解读:

在这里插入图片描述

在这里插入图片描述

2、模拟一个文本编辑的界面(使用控件:Grid | StackPanel | Button | TextBox)

准备

button的属性: Width HorizontalAlignment VerticalAlignment Height
在这里插入图片描述

    <Grid><Button Width="200" HorizontalAlignment="Left" VerticalAlignment="Top" Height="40"/><Button Width="200" HorizontalAlignment="Center" VerticalAlignment="Top" Height="40"/><Button Width="200" HorizontalAlignment="Right" VerticalAlignment="Top" Height="40"/><Button Width="200" HorizontalAlignment="Left" VerticalAlignment="Center" Height="40"/><Button Width="200" HorizontalAlignment="Center" VerticalAlignment="Center" Height="40"/><Button Width="200" HorizontalAlignment="Right" VerticalAlignment="Center" Height="40"/><Button Width="200" HorizontalAlignment="Left" VerticalAlignment="Bottom" Height="40"/><Button Width="200" HorizontalAlignment="Center" VerticalAlignment="Bottom" Height="40"/><Button Width="200" HorizontalAlignment="Right" VerticalAlignment="Bottom" Height="40"/></Grid>

Stackanel控件:
.在这里插入图片描述

占用多列的写法:
Grid.ColumnSpan=“2”

        <StackPanel Orientation="Vertical" HorizontalAlignment="Center"><Button Height="20" Width="70"/><Button Height="20" Width="70"/><Button Height="20" Width="70"/></StackPanel>

在这里插入图片描述

        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"><Button Height="20" Width="70"/><Button Height="20" Width="70"/><Button Height="20" Width="70"/></StackPanel>

Grid控件:
在这里插入图片描述

    <Grid ShowGridLines="True"><Grid.RowDefinitions><RowDefinition Height="1*"/><RowDefinition Height="1*"/><RowDefinition Height="1*"/><RowDefinition Height="1*"/></Grid.RowDefinitions><Grid.ColumnDefinitions><ColumnDefinition Width="1*"/><ColumnDefinition Width="1*"/><ColumnDefinition Width="1*"/><ColumnDefinition Width="1*"/><ColumnDefinition Width="1*"/></Grid.ColumnDefinitions><Button Grid.Row="1" Grid.Column="1">1,1</Button><Button Grid.Row="1" Grid.Column="2">1,2</Button><Button Grid.Row="1" Grid.Column="3">1,3</Button><Button Grid.Row="2" Grid.Column="1">2,1</Button><Button Grid.Row="2" Grid.Column="2">2,2</Button><Button Grid.Row="2" Grid.Column="3">2,3</Button></Grid>

Grid 的三种长度设置:
AUTO 安内容来
绝对宽高 每个单位是 1/96英寸
“1*” 按比例来

TextBox 文本编辑的控件

在这里插入图片描述

        <TextBox TextWrapping="Wrap"/>

应用

在这里插入图片描述

<Window x:Class="WpfApp1.EditWindow"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:WpfApp1"mc:Ignorable="d"Title="EditWindow" Height="450" Width="800"><Grid><Grid.RowDefinitions><RowDefinition Height="20"/><RowDefinition Height="20"/><RowDefinition Height="1*"/><RowDefinition Height="20"/></Grid.RowDefinitions><StackPanel Grid.Row="0" Grid.Column="0" Orientation="Horizontal"><Button Height="20" Width="70" Content="文件"/><Button Height="20" Width="70" Content="编辑"/><Button Height="20" Width="70" Content="查看"/><Button Height="20" Width="70" Content="外观"/><Button Height="20" Width="70" Content="设置"/></StackPanel><StackPanel Grid.Row="1" Grid.Column="0" Orientation="Horizontal"><Button Height="20" Width="20" Content="1"/><Button Height="20" Width="20" Content="2"/><Button Height="20" Width="20" Content="3"/><Button Height="20" Width="20" Content="4"/><Button Height="20" Width="20" Content="5"/></StackPanel><Grid Grid.Row="2" Grid.Column="0"><Grid><Grid.ColumnDefinitions><ColumnDefinition Width="40"/><ColumnDefinition/></Grid.ColumnDefinitions><StackPanel Grid.Column="0" Grid.Row="0"><Button Height="20" Content="1"/><Button Height="20" Content="2"/><Button Height="20" Content="3"/><Button Height="20" Content="4"/><Button Height="20" Content="5"/><Button Height="20" Content="6"/><Button Height="20" Content="7"/><Button Height="20" Content="8"/><Button Height="20" Content="9"/><Button Height="20" Content="10"/><Button Height="20" Content="11"/><Button Height="20" Content="12"/><Button Height="20" Content="13"/><Button Height="20" Content="14"/><Button Height="20" Content="15"/><Button Height="20" Content="16"/><Button Height="20" Content="17"/></StackPanel><TextBox Grid.Column="1" TextWrapping="Wrap"/></Grid></Grid><Grid Grid.Row="3" Grid.Column="0"><Grid.ColumnDefinitions><ColumnDefinition Width="auto"/><ColumnDefinition Width="1*"/><ColumnDefinition Width="1*"/><ColumnDefinition Width="1*"/><ColumnDefinition Width="1*"/><ColumnDefinition Width="1*"/><ColumnDefinition Width="1*"/><ColumnDefinition Width="1*"/></Grid.ColumnDefinitions><Button Grid.Column="0">Normal text file</Button><Button Grid.Column="1">Length:1,125</Button><Button Grid.Column="2">lines:26</Button><Button Grid.Column="3">Ln:6 Col:57 Sel:3</Button><Button Grid.Column="4">1</Button><Button Grid.Column="5">Windows(CR LF)</Button><Button Grid.Column="6">UTF-8-BOM</Button><Button Grid.Column="7">INS</Button></Grid></Grid>
</Window>

2-2 布局器的使用:

1、StackPanel 水平或垂直排列元素、Orientation 属性分别为:Horizontal / Verical

在这里插入图片描述

在这里插入图片描述

2、WrapPanel 水平或垂直排列元素、剩余控件不足会进行换行、换列的排布

在这里插入图片描述
在这里插入图片描述

3、DockPanel 根据容器的边界、元素进行 Dock.Top 、Left 、Right 、Bottom

在这里插入图片描述

4、Grid 类似 table表格

在这里插入图片描述

5、UniformGrid 指定行和列的数量,均匀有限的容器空间

在这里插入图片描述

6、Canvas 使用固定的坐标设置元素的位置

在这里插入图片描述

3、样式

在这里插入图片描述

样式写在:

< Window.Resources > 里的 < Style > 里 //定义
在标签里加属性Style: Style=“{StaticResource LoginStyle}” //使用

StaticResource 静态加载
DynamicResource 动态加载,在运行的时候,改变 xaml 文件内容,样式是会发生改变的

	<Window x:Class="WpfApp1.EditWindow"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:WpfApp1"mc:Ignorable="d"Title="EditWindow" Height="450" Width="800"><Window.Resources><Style TargetType="Button"><Setter Property="Background" Value="WhiteSmoke"/><Setter Property="FontSize" Value="20"/><Setter Property="Height" Value="50"/><Setter Property="Width" Value="300"/><Setter Property="Margin" Value="20,10"/></Style><Style x:Key="LoginStyle"  TargetType="Button"><Setter Property="Background" Value="Green"/><Setter Property="FontSize" Value="20"/><Setter Property="Height" Value="50"/><Setter Property="Width" Value="300"/></Style><Style x:Key="QuitStyle"  TargetType="Button" BasedOn="{StaticResource {x:Type Button} }"><Setter Property="Background" Value="Red"/></Style></Window.Resources><StackPanel><Button Style="{StaticResource LoginStyle}" Content="登录"/><Button Style="{DynamicResource QuitStyle}" Content="退出"/><Button Content="忘记密码"/></StackPanel></Window>

继承:

在这里插入图片描述

<Window x:Class="WpfApp1.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="登录界面" Height="270" Width="500" ResizeMode="NoResize"><Window.Resources><Style x:Key="baseButtonStyle" TargetType="Button"><Setter Property="FontSize" Value="30"/><Setter Property="Foreground" Value="Blue"/></Style><Style x:Key="defaultButtonStyle" TargetType="Button" BasedOn="{StaticResource baseButtonStyle}"><Setter Property="Width" Value="100"/><Setter Property="Height" Value="50"/></Style></Window.Resources><Grid><Button Style="{StaticResource defaultButtonStyle}" Content="ghyu"/></Grid>
</Window>

4、添加资源字典

第一步:添加资源字典 xaml 文件

在这里插入图片描述
资源字典文件:Dictionary1.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"><Style TargetType="Button"><Setter Property="Background" Value="WhiteSmoke"/><Setter Property="FontSize" Value="20"/><Setter Property="Height" Value="50"/><Setter Property="Width" Value="300"/><Setter Property="Margin" Value="20,10"/></Style><Style x:Key="LoginStyle"  TargetType="Button"><Setter Property="Background" Value="Green"/><Setter Property="FontSize" Value="20"/><Setter Property="Height" Value="50"/><Setter Property="Width" Value="300"/></Style><Style x:Key="QuitStyle"  TargetType="Button" BasedOn="{StaticResource {x:Type Button} }"><Setter Property="Background" Value="Red"/></Style>
</ResourceDictionary>

第二步:在 app.xml 文件中引入 资源字典文件

            <ResourceDictionary Source="/WpfApp1;component/Dictionary1.xaml"/>这里的  WpfApp1  是  命名空间Dictionary1.xaml  是  要加载的文件名
<Application x:Class="WpfApp1.App"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="clr-namespace:WpfApp1"StartupUri="EditWindow.xaml"><Application.Resources><ResourceDictionary><ResourceDictionary.MergedDictionaries><ResourceDictionary Source="/WpfApp1;component/Dictionary1.xaml"/></ResourceDictionary.MergedDictionaries></ResourceDictionary></Application.Resources>
</Application>

第三步:在标签中,可以直接调用

在这里插入图片描述

<Window x:Class="WpfApp1.EditWindow"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:WpfApp1"mc:Ignorable="d"Title="EditWindow" Height="450" Width="800"><StackPanel><Button Style="{StaticResource LoginStyle}" Content="登录"/><Button Style="{DynamicResource QuitStyle}" Content="退出"/><Button Content="忘记密码"/></StackPanel>
</Window>

5、用模板自定义一个带圆角的 Button 控件 及 触发器 的写法

在这里插入图片描述

            <ControlTemplate TargetType="Button">

里 TargetType=“Button” 和 TargetTye=“{x:Type Button}” 是一样的

                <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="6">

在这一行中,{TemplateBinding Background}" 表示从原 button 标签中去取 叫 Background 的属性

<Window x:Class="WpfApp1.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:WpfApp1"mc:Ignorable="d"Title="123" Height="450" Width="800"><Grid><Button Content="btn" Background="Red" BorderBrush="Black" FontSize="20" Width="200" Height="30" BorderThickness="3"><Button.Template><ControlTemplate TargetType="Button"><Border x:Name="boder" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="6"><TextBlock Text="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/></Border><ControlTemplate.Triggers><Trigger Property="IsMouseOver" Value="True"><Setter TargetName="boder" Property="Background" Value="Black"/></Trigger><Trigger Property="IsPressed" Value="True"><Setter TargetName="boder" Property="Background" Value="WhiteSmoke"/></Trigger></ControlTemplate.Triggers></ControlTemplate></Button.Template></Button></Grid>
</Window>

解读:

Grid: 一个布局容器,用于布局子元素。在这个例子中,它包含了一个 Button 控件。

Button: 一个按钮控件,具有以下属性:
Content=“btn”: 按钮的显示文本为 “btn”。
Background=“Red”: 按钮的背景颜色为红色。
BorderBrush=“Black”: 按钮的边框颜色为黑色。
FontSize=“20”: 按钮文本的字体大小为 20。
Width=“200”: 按钮的宽度为 200 像素。
Height=“30”: 按钮的高度为 30 像素。
BorderThickness=“3”: 按钮的边框厚度为 3 像素。

ControlTemplate: 定义了 Button 控件的外观模板。TargetType=“Button” 指定这个模板用于 Button 控件。
Border: 包含了按钮的主要视觉部分。
x:Name=“boder”: 给 Border 起了一个名字 boder,以便在触发器中引用。
Background=“{TemplateBinding Background}”: Border 的背景颜色绑定到按钮的 Background 属性。
BorderBrush=“{TemplateBinding BorderBrush}”: Border 的边框颜色绑定到按钮的 BorderBrush 属性。
BorderThickness=“{TemplateBinding BorderThickness}”: Border 的边框厚度绑定到按钮的 BorderThickness 属性。
CornerRadius=“6”: Border 的圆角半径设置为 6 像素,使边角有一定的圆润效果。
TextBlock: 显示按钮的文本内容。
Text=“{TemplateBinding Content}”: TextBlock 的文本绑定到按钮的 Content 属性。
HorizontalAlignment=“Center”: 文本在水平方向居中对齐。
VerticalAlignment=“Center”: 文本在垂直方向居中对齐.
在这里插入图片描述
在这里插入图片描述

5-2、触发器 的另一些实践

<Window x:Class="WpfApp1.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="登录界面" Height="270" Width="500"><Window.Resources><Style x:Key="defaultButtonStyle" TargetType="Button"><Setter Property="Width" Value="100"/><Setter Property="Height" Value="30"/><Style.Triggers><Trigger Property="IsMouseOver" Value="True"><Setter Property="Foreground" Value="Red"/><Setter Property="FontSize" Value="30"/></Trigger><Trigger Property="IsMouseOver" Value="False"><Setter Property="Foreground" Value="Blue"/><Setter Property="FontSize" Value="20"/></Trigger></Style.Triggers></Style><Style x:Key="defaultButtonStyle2" TargetType="Button"><Setter Property="Width" Value="100"/><Setter Property="Height" Value="30"/><Style.Triggers><MultiTrigger><MultiTrigger.Conditions><Condition Property="IsMouseOver" Value="true"/><Condition Property="IsFocused" Value="True"/></MultiTrigger.Conditions><MultiTrigger.Setters><Setter Property="Foreground" Value="Red"/></MultiTrigger.Setters></MultiTrigger></Style.Triggers></Style><Style x:Key="defaultButtonStyle3" TargetType="Button"><Setter Property="Width" Value="100"/><Setter Property="Height" Value="30"/><Style.Triggers><EventTrigger RoutedEvent="Mouse.MouseEnter"><EventTrigger.Actions><BeginStoryboard><Storyboard><DoubleAnimation Duration="0:0:0.2"Storyboard.TargetProperty="FontSize"To="30"></DoubleAnimation></Storyboard></BeginStoryboard></EventTrigger.Actions></EventTrigger></Style.Triggers></Style></Window.Resources><StackPanel><Button Style="{StaticResource defaultButtonStyle}" Content="Hello"/><Button Style="{StaticResource defaultButtonStyle2}" Content="Hello"/><Button Style="{StaticResource defaultButtonStyle3}" Content="Hello"/></StackPanel>
</Window>

5-3、生成模板副本:

在这里插入图片描述

在这里插入图片描述
将 模板放在 资源字典中:
在这里插入图片描述

5-4、控件模板

在这里插入图片描述

5-5、数据模板

第一个例子:
在这里插入图片描述
在这里插入图片描述
第二个例子:
在这里插入图片描述
在这里插入图片描述

6、 button 的 和 点击事件 的写法:

在这里插入图片描述

6-2、添加点击事件的两种方式:

1 直接在 xaml 代码中进行添加
2 根据名字找到控件的 点击事件,在 cs 代码中添加
在这里插入图片描述

<Window x:Class="WpfApp1.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:sys="clr-namespace:System;assembly=mscorlib"Title="MainWindow" Height="450" Width="800"><Window.Resources><sys:String x:Key="stringHello">Hello WPF!</sys:String></Window.Resources><Grid><TextBlock Height="24" Width="120" Background="LightBlue"Text="{StaticResource ResourceKey=stringHello}"/></Grid>
</Window>

7-1、控件间的属性绑定

在这里插入图片描述

    <Grid><StackPanel><Slider x:Name="slider" Margin="5"/><TextBoxHeight="30"Margin="5"Text="{Binding ElementName=slider, Path=Value, Mode=OneTime}"/><!--只进行一次绑定--><TextBoxHeight="30"Margin="5"Text="{Binding ElementName=slider, Path=Value, Mode=OneWay}"/><!--单向绑定--><TextBoxHeight="30"Margin="5"Text="{Binding ElementName=slider, Path=Value}"/><!--默认是双向绑定--></StackPanel></Grid>

7-2、一个简单的数据绑定的写法(属性的变更通知)

完成前 3 步,可以实现 数据从界面 向 代码的传递
完成后 2 步,可以实现 界面 向 代码层的数据传递
在这里插入图片描述

在这里插入图片描述

代码:

在这里插入图片描述

<Window x:Class="WpfApp1.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:WpfApp1"mc:Ignorable="d"Title="登录界面" Height="270" Width="500" ResizeMode="NoResize"><Grid><Grid.RowDefinitions><RowDefinition Height="15"/><RowDefinition Height="30"/><RowDefinition Height="auto"/><RowDefinition Height="5*"/></Grid.RowDefinitions><TextBox Grid.Row="1" Text="X6337TEB6----登录系统" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="16"/><Grid Grid.Row="2"><Grid.RowDefinitions><RowDefinition Height="20"/><RowDefinition Height="20"/><RowDefinition Height="20"/><RowDefinition Height="27"/></Grid.RowDefinitions><Grid.ColumnDefinitions><ColumnDefinition Width="1*"/><ColumnDefinition Width="auto"/><ColumnDefinition Width="150"/><ColumnDefinition Width="1*"/></Grid.ColumnDefinitions><TextBlock Grid.Row="0" Grid.Column="1" Text="用户名"/><TextBox Text ="{Binding UserName}" Grid.Row="0" Grid.Column="2" Margin="3,2"/><TextBlock Grid.Row="1" Grid.Column="1" Text="密码"/><TextBox Text="{Binding PassWord}" Grid.Row="1" Grid.Column="2" Margin="3,2"/><CheckBox Grid.ColumnSpan="2"  Grid.Row="2" Grid.Column="1" Content="记住密码"/><Button Grid.ColumnSpan="2" Grid.Row="3" Grid.Column="1" Content="登录" Margin="3,1" Click="Button_Click"/></Grid></Grid>
</Window>
using System;
using System.ComponentModel;
using System.Windows;namespace WpfApp1
{/// <summary>/// MainWindow.xaml 的交互逻辑/// </summary>public partial class MainWindow : Window,INotifyPropertyChanged{#region 数据绑定的固定写法private string _userName;private string _passWord;public string UserName {get { return _userName; }set { _userName = value;RaisePropertyChanged("UserName");} }public string PassWord {get { return _passWord; } set {_passWord = value;RaisePropertyChanged("PassWord");} }public event PropertyChangedEventHandler PropertyChanged;private void RaisePropertyChanged(string propertyName){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}#endregionpublic MainWindow(){InitializeComponent();this.DataContext = this;}/// <summary>/// 登录按钮/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void Button_Click(object sender, RoutedEventArgs e){Console.WriteLine($"{UserName}-{PassWord}");UserName = "Admin";PassWord = "123";}}
}

8、MVVM(与 7 是同一个界面)

MVVM是为里前后端的分离
MVVM与MVC,VM 是对 C 的升级(依靠的是 双向的数据属性 和 单向的命令属性)
V 的修改 不会影响到 其他部分代码的编译

MVVM 和 MVC 的区别
MVVM
M Model
V View
VM ViewModel
在这里插入图片描述

MVC
M Model
V View
C Control
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

8-1.1 带参的方法的写法:

传入 Tag

<Button Grid.Row="0" Command="{Binding ClickBtn}" Tag="a" CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=Tag}">a</Button>
public ICommand ClickBtn
{get{return new ExecuteCommond((param) =>{// param 是 CommandParameter 传递的值string tag = param as string;Console.WriteLine($"Tag: {tag}");});}
}

传入控件自身

<Button Grid.Row="0" Command="{Binding ClickBtn}" Tag="a" CommandParameter="{Binding RelativeSource={RelativeSource Self}}">a</Button>
public ICommand ClickBtn
{get{return new ExecuteCommond((param) =>{if (param is Button button){var tag = button.Tag; // 获取按钮的Tag属性Console.WriteLine($"Tag: {tag}");}});}
}

多种入参的 ICommand 的实现

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;namespace QIPWaterDeal.ViewModel
{public class ExecuteCommond : ICommand{/// <summary>/// 判断命令是否可以执行/// </summary>private readonly Func<bool> _canExecute;/// <summary>/// 执行无参数的操作/// </summary>private readonly Action _execute;/// <summary>/// 执行带参数的操作/// </summary>private readonly Action<object> _executeWithParameter;/// <summary>/// 构造方法(无参数版本)/// </summary>public ExecuteCommond(Action execute, Func<bool> canExecute = null){_execute = execute;_canExecute = canExecute;}/// <summary>/// 构造方法(带参数版本)/// </summary>public ExecuteCommond(Action<object> executeWithParameter, Func<bool> canExecute = null){_executeWithParameter = executeWithParameter;_canExecute = canExecute;}public event EventHandler CanExecuteChanged;/// <summary>/// 是否可以执行命令/// </summary>public bool CanExecute(object parameter){return _canExecute == null || _canExecute();}/// <summary>/// 执行命令/// </summary>public void Execute(object parameter){if (_execute != null){_execute.Invoke();}else if (_executeWithParameter != null){_executeWithParameter.Invoke(parameter);}}/// <summary>/// 通知CanExecute状态发生变化/// </summary>public void RaiseCanExecuteChanged(){CanExecuteChanged?.Invoke(this, EventArgs.Empty);}}
}

8-2 MVVM的另一种实践(对 进行包装)

在这里插入图片描述

一个实际的例子
在这里插入图片描述
在这里插入图片描述

MainWindow.xml

<Window x:Class="WpfApp1.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="登录界面" Height="270" Width="500" ResizeMode="NoResize"><Grid><StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"><TextBox x:Name="input1" Width="100" Height="24" Margin="3" Text="{Binding Input1}"></TextBox><TextBox x:Name="input2" Width="100" Height="24" Margin="3" Text="{Binding Input2}"></TextBox><TextBox x:Name="input3" Width="100" Height="24" Margin="3" Text="{Binding Input3}"></TextBox><Button x:Name="btn1" Width="100" Height="24" Margin="3" Content="Add" Command="{Binding AddCommand}"></Button></StackPanel></Grid>
</Window>

NotificationObject

using System.ComponentModel;namespace WpfApp1
{/// <summary>/// VM 的基类/// </summary>public class NotificationObject:INotifyPropertyChanged{public event PropertyChangedEventHandler PropertyChanged;public void RaisePropertyChange(string propertyName){if(this.PropertyChanged != null){this.PropertyChanged.Invoke(this,new PropertyChangedEventArgs(propertyName));}}}
}

DelegateCommand

using System;
using System.Windows.Input;namespace WpfApp1
{public class DelegateCommand:ICommand{public bool CanExecute(object parameter){if(this.CanExecuteFunc == null){return true;}return this.CanExecuteFunc(parameter);}public event EventHandler CanExecuteChanged;public void Execute(object parameter){if(this.ExecuteAction == null){return;}this.ExecuteAction(parameter);}public Action<object> ExecuteAction { get; set; }public Func<object,bool> CanExecuteFunc { get; set; }}
}

MainWindowViewModel

using System;namespace WpfApp1
{internal class MainWindowViewModel : NotificationObject{#region 数据属性private double input1;public double Input1 {get{ return input1;}set { input1 = value;this.RaisePropertyChange(nameof(Input1));}}private double input2;public double Input2 {get{return input2;}set{input2 = value;this.RaisePropertyChange(nameof(Input2));}}private double input3;public double Input3 {get {return input3;}set {input3 = value;this.RaisePropertyChange(nameof(Input3));}}#endregion#region 命令属性public DelegateCommand AddCommand { get; set; }private void Add(object parameter){this.Input3 = this.Input1 + this.Input2;}public MainWindowViewModel(){this.AddCommand = new DelegateCommand();this.AddCommand.ExecuteAction = new Action<object>(this.Add);}#endregion}
}

8-3、利用 特性(反射),优化数据变更通知(接口)的写法

在这里插入图片描述

9、写一个自定义控件(添加 自定义 依赖属性)

在这里插入图片描述
字典资源
在这里插入图片描述
加入字典资源
在这里插入图片描述

继承 Button 的自定义控件
在这里插入图片描述
使用:
在这里插入图片描述

10、导入程序集和引用其中的名称空间:

在这里插入图片描述

然后选 带 Framework 的
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

<UserControl x:Class="WpfControlLibrary3.UserControl1"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfControlLibrary3"mc:Ignorable="d" d:DesignHeight="160" d:DesignWidth="240"><Grid><Canvas><Label Canvas.Left="12" Canvas.Top="12" Content="第一部分" Height="28" Name="label1"/><Label Canvas.Left="12" Canvas.Top="46" Content="第二部分" Height="28" Name="label2"/><Label Canvas.Left="12" Canvas.Top="80" Content="第三部分" Height="28" Name="label3"/><TextBox Canvas.Left="88" Canvas.Top="14" Height="23" Name="textBox1" Width="140"/><TextBox Canvas.Left="88" Canvas.Top="48" Height="23" Name="textBox2" Width="140"/><TextBox Canvas.Left="88" Canvas.Top="82" Height="23" Name="textBox3" Width="140"/><Button Canvas.Left="88" Canvas.Top="125" Content="计算" Height="23" Name="button1" Width="140" Click="button_Click"/></Canvas></Grid>
</UserControl>

添加引用:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

11、一些 x 命名空间的使用

x:Class
在这里插入图片描述

x:ClassModifier
在这里插入图片描述
x:Name
在这里插入图片描述
x:FieldModifier
在这里插入图片描述

12、在WPF中加载 Winform 的 Form

1、在wpf 中添加引用

System.Windows.Forms.Integration

System.Windows.Forms.Integration
注:System.Windows.Forms.Integration 在 Net Formwork 4.7.2 中叫 WindowsFormsIntegration
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

2、创建用户控件

在wpf 项目中创建 winform 控件

using System.Windows.Forms;
using WindowsFormsControlLibrary1;namespace WpfApp1
{public partial class UserControl1 : UserControl{private Form1 _form1;public UserControl1(){InitializeComponent();_form1 = new Form1();_form1.TopLevel = false;_form1.Dock = DockStyle.Fill;this.Controls.Add(_form1);_form1.Show();}}
}

在 主界面中 WindowsFormsHost 加入标签,在代码中加载 Winform 的控件,借助Winform控件 加载 winform 窗体

    <Grid><WindowsFormsHost Name="windowsFormsHost" /></Grid>   
using System.Windows;
namespace WpfApp1
{/// <summary>/// MainWindow.xaml 的交互逻辑/// </summary>public partial class MainWindow : Window{public MainWindow(){InitializeComponent();UserControl1 userControl1 = new UserControl1();windowsFormsHost.Child = userControl1;}}
}

13、动画

动画有三种:
线性动画:DouleAnmim
关键帧动画:DoubleAnimationUsingkeyFrams
路径动画:DoubleAnimationUsingPath
在这里插入图片描述

    <Grid><StackPanel><Button x:Name="btn" Width="100" Height="24" Content="带动画的按钮" Click="Button_Click"/><Button x:Name="btn2" Width="100" Height="24" Content="带动画的按钮" Click="Button_Click2"/><Button x:Name="btn3" Width="100" Height="24" Content="带动画的按钮" Click="Button_Click3"/></StackPanel></Grid>
#define C
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;
namespace WpfApp1
{/// <summary>/// MainWindow.xaml 的交互逻辑/// </summary>public partial class MainWindow : Window{public MainWindow(){InitializeComponent();}private void Button_Click(object sender, RoutedEventArgs e){//创建一个双精度的动画DoubleAnimation animation = new DoubleAnimation();animation.From = btn.Width;//设置动画的初始值animation.To = btn.Width - 30;//设置动画的结束值animation.Duration = TimeSpan.FromSeconds(2);//设置动画的持续时间//在当前按钮上实行该动画btn.BeginAnimation(Button.WidthProperty,animation);}private void Button_Click2(object sender, RoutedEventArgs e){//创建一个双精度的动画DoubleAnimation animation = new DoubleAnimation();animation.From = btn2.Width;//设置动画的初始值animation.To = btn2.Width - 30;//设置动画的结束值animation.Duration = TimeSpan.FromSeconds(2);//设置动画的持续时间animation.AutoReverse = true;  //是否往返执行animation.RepeatBehavior = RepeatBehavior.Forever; //执行周期//在当前按钮上实行该动画btn2.BeginAnimation(Button.WidthProperty,animation);}private void Button_Click3(object sender, RoutedEventArgs e){//创建一个双精度的动画DoubleAnimation animation = new DoubleAnimation();animation.From = btn3.Width;//设置动画的初始值animation.To = btn3.Width - 30;//设置动画的结束值animation.Duration = TimeSpan.FromSeconds(2);//设置动画的持续时间animation.AutoReverse = true;  //是否往返执行animation.RepeatBehavior = new RepeatBehavior(5);//重复5次animation.Completed += Animation_Completed;//动画结束的回调//在当前按钮上实行该动画btn3.BeginAnimation(Button.WidthProperty,animation);}private void Animation_Completed(object sender,EventArgs e){btn3.Content = "动画已完成";}}}

14、WPF 和 Prism

其他

1、获取当前文件目录

string currentDirectory = AppDomain.CurrentDomain.BaseDirectory;

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

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

相关文章

今日行情明日机会——20250217

2025年02月17日行情 后续投资机会分析 根据最新盘面信息&#xff0c;以下板块和个股具备潜在投资机会&#xff0c;需结合市场动态和基本面进一步验证&#xff1a; 1. 腾讯系AI&#xff08;18家涨停&#xff09; 核心逻辑&#xff1a;涨停家数最多&#xff08;18家&#xff0…

常见的IP地址分配方式有几种:深入剖析与适用场景‌

在数字互联的世界里&#xff0c;IP地址如同网络世界的“门牌号”&#xff0c;是设备间通信的基础。随着网络技术的飞速发展&#xff0c;IP地址的分配方式也日趋多样化&#xff0c;以适应不同规模、不同需求的网络环境。本文将深入探讨当前主流的几种IP地址分配方式&#xff0c;…

快速搭建 OLLAMA + DeepSeek 模型并对接 Cherry Studio

快速搭建 OLLAMA DeepSeek 模型并对接 Cherry Studio 本文将指导您在基于 GPU 的 Ubuntu 服务器上快速搭建 OLLAMA&#xff0c;部署 DeepSeek 模型&#xff0c;并接入 Cherry Studio 进行使用。 环境说明 GPU 服务器: GeForce RTX 2080 Ti, 16 核, 64G 内存系统: Ubuntu 24.…

floodfill算法系列一>扫雷游戏

目录 题目思路&#xff1a;代码设计&#xff1a;代码呈现&#xff1a; 题目思路&#xff1a; 代码设计&#xff1a; 代码呈现&#xff1a; class Solution {int m,n;int[] dx {0,0,-1,1,-1,-1,1,1};int[] dy {-1,1,0,0,-1,1,-1,1};public char[][] updateBoard(char[][] boa…

【附带脚本】解决notion加载慢问题

问题原因 notion网站的服务器在国外&#xff0c;因为网络问题&#xff08;国际出口带宽限制&#xff09;导致访问速度较慢和域名解析延迟等问题。 解决方案 通过在 hosts 文件中直接指定一个更快的 IP 地址&#xff08;例如国内镜像服务器&#xff09;&#xff0c;可以显著提…

Banana Pi OpenWRT One 官方路由器的第一印象

OpenWRT One是OpenWRT开源社区推出的首款官方开发板&#xff0c;与Banana Pi社区共同设计&#xff0c;由Banana Pi制造和发行。路由器采用蓝色铝合金外壳&#xff0c;质感极佳&#xff0c;视觉效果远超宣传图。整体设计简洁&#xff0c;呈长方形&#xff0c;虽然不是特别时尚&a…

花西子携手赛博威共创新品创新平台,驱动“新质美力”高质量发展

国货彩妆品牌花西子与赛博威信息科技达成【新品创新平台】项目合作&#xff0c;共探“新质美力”的高质量发展路径。 近日&#xff0c;赛博威信息科技CEO陈国平携团队走进花西子“百年之诗”馆&#xff0c;深入了解花西子的品牌理念、企业文化及百年愿景&#xff0c;并与花西子…

[JVM篇]垃圾回收器

垃圾回收器 Serial Seral Old PartNew CMS(Concurrent Mark Sweep) Parallel Scavenge Parallel Old G1 ZGC

在VScode内接入deepseek(本地部署版包会)

目录 1. 首先得有vscode软件 2. 在我们的电脑本地已经部署了ollama&#xff0c;我将以qwen作为实验例子 3. 在vscode上的扩展商店下载continue 4. 下载完成后&#xff0c;依次点击添加模型 5. 在这里可以添加&#xff0c;各种各样的模型&#xff0c;选择我们的ollama 6. 选…

应对DeepSeek总是服务器繁忙的解决方法

最近由于访问量过大&#xff0c;DeepSeek服务器官网经常弹出&#xff1a;“服务器繁忙&#xff0c;请稍后再试”的提示&#xff0c;直接卡成PPT怎么办&#xff1f;服务器繁忙直接看到视觉疲劳&#xff1a; 解决DeepSeek卡顿问题 DeepSeek使用卡顿问题&#xff0c;是因为访问量…

游戏引擎学习第107天

仓库:https://gitee.com/mrxiao_com/2d_game_2 回顾我们之前停留的位置 在这段内容中&#xff0c;讨论了如何处理游戏中的三维效果&#xff0c;特别是如何处理额外的“Z层”。由于游戏中的艺术资源是位图而不是3D模型&#xff0c;因此实现三维效果变得非常具有挑战性。虽然可…

sql盲注脚本

在sqli-labs中的第8题无回显可以尝试盲注的手法获取数据 发现页面加载了3秒左右可以进行盲注 布尔盲注数据库名 import requestsdef inject_database(url):datanamefor i in range(1,15):low 32high 128mid (low high) // 2while low < high:path "id1 and asci…

文字识别产品、文档识别系统、表格识别API

文字识别技术让文字录入工作不再繁琐。人工智能时代&#xff0c;文字识别接口产品运用先进的光学字符识别与图像处理技术&#xff0c;衍生了一系列图像文字快速提取的应用场景。无论是扫描文件、照片文字还是PDF文档&#xff0c;文字识别接口都能轻松应对。支持对中文简体、中文…

springcloud集成gateway

本篇文章只介绍gateway模块的搭建步骤&#xff0c;并无gateway详细介绍 gateway详解请查看&#xff1a;SpringCloudGateway官方文档详解 前置处理 父模块中已指定版本 不知道如何选择版本看这篇&#xff1a; 手把手教你梳理springcloud与springboot与springcloudalibaba的版本…

建筑兔零基础自学python记录22|实战人脸识别项目——视频人脸识别(下)11

这次我们继续解读代码&#xff0c;我们主要来看下面两个部分&#xff1b; 至于人脸识别成功的要点我们在最后总结~ 具体代码学习&#xff1a; #定义人脸名称 def name():#预学习照片存放位置path M:/python/workspace/PythonProject/face/imagePaths[os.path.join(path,f) f…

LabVIEW太阳能制冷监控系统

在全球能源需求日益增长的背景下&#xff0c;太阳能作为一种无限再生能源&#xff0c;被广泛应用于各种能源系统中。本基于LabVIEW软件和STM32F105控制器的太阳能制冷监控系统的设计与实现&#xff0c;提供一个高效、经济的太阳能利用方案&#xff0c;以应对能源消耗的挑战。 项…

AIGC图生视频保姆级教程

一、AI文生图高阶技巧 推荐工具 ▸ MidJourney&#xff08;艺术感最强&#xff09; ▸ DALLE 3&#xff08;与ChatGPT深度联动&#xff09; ▸ Leonardo.ai&#xff08;精细化参数控制&#xff09; 核心策略 提示词架构&#xff1a; [主体描述][环境氛围][镜头语言][风格参数…

嵌入式EasyRTC实时通话支持海思hi3516cv610,编译器arm-v01c02-linux-musleabi-gcc

EasyRTC已经完美支持海思hi3516cv610&#xff0c;编译器arm-v01c02-linux-musleabi-gcc&#xff0c;总体SDK大小控制在680K以内&#xff08;预计还能压缩100K上下&#xff09;&#xff1a; EasyRTC在hi3516cv610芯片上能双向通话、发送文字以及二进制指令&#xff0c;总体运行…

力扣做题记录 (二叉树)

二叉树 打算先来了解二叉树基础&#xff0c;都是简单题&#xff0c;目的是熟悉代码格式和解题基础思路。 1、二叉树最大深度 二叉树最大深度 方法一、深度搜索 直接用原函数做递归&#xff0c;比较简单 /*** Definition for a binary tree node.* struct TreeNode {* …

如何下载Qt和运行第一个程序。

Ubuntu24.04 下载比较容易&#xff0c;基本都是无脑操作。途中汇出现有个别package下载不成功的情况&#xff0c;重新下载即可。 文章目录 下载qt运行qt第一个项目 下载qt 1.先找到官网&#xff0c;点击Download。 2.然后选择&#xff0c;community User 3.然后会跳转到这个…