WPF组合控件TreeView+DataGrid之TreeView封装
(关注博主后,在“粉丝专栏”,可免费阅读此文)
wpf的功能非常强大,很多控件都是原生的,但是要使用TreeView+DataGrid的组合,就需要我们自己去封装实现。
我们需要的效果如图所示:
这2个图都是第三方控件自带的,并且都是收费使用。
现在我们就用原生的控件进行封装一个。
本文源码效果如下,(搞了好几天,的确有难度,所以源码也收费,便宜,赚点辛苦费)
功能如图所示, 目前已经实现了一部分。
首先说明一下,实现上面的效果,有3种方法
第一种:技术的选择是TreeView(也就是本文的演示)。
第二种:技术的选择是DataGrid。
第三种:技术的选择是ListView。
本文演示的是使用TreeView的实现。
1.首先建立一个wpf程序
2. 封装TreeGrid
namespace TreeView.TreeDataGrid.Controls
{//这里有一个骚操作,就是把引用放在里面using System;using System.Collections.Specialized;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Media;public class TreeGrid : TreeView{static TreeGrid(){DefaultStyleKeyProperty.OverrideMetadata(typeof(TreeGrid), new FrameworkPropertyMetadata(typeof(TreeGrid)));}#region ColumnMappings DependencyPropertypublic string ColumnMappings{get { return (string)GetValue(ColumnMappingsProperty); }set { SetValue(ColumnMappingsProperty, value); }}public static readonly DependencyProperty ColumnMappingsProperty =DependencyProperty.Register("ColumnMappings", typeof(string), typeof(TreeGrid),new PropertyMetadata("", new PropertyChangedCallback(TreeGrid.OnColumnMappingsPropertyChanged)));private static void OnColumnMappingsPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e){if (obj is TreeGrid){(obj as TreeGrid).OnColumnMappingsValueChanged();}}protected void OnColumnMappingsValueChanged(){if (!string.IsNullOrEmpty(ColumnMappings)){ResetMappingColumns(ColumnMappings);}}private void ResetMappingColumns(string mapping){GridViewColumnCollection items = new GridViewColumnCollection();var columns = mapping.Split(new char[] { ';', '|' }, StringSplitOptions.RemoveEmptyEntries);foreach (var c in columns){var index = c.IndexOf(':');var title = "";var name = "";if (index > 0){title = c.Substring(0, index);name = c.Substring(index + 1);}else{title = c;name = c;}DataTemplate temp = null;var res = this.FindTreeResource<DataTemplate>(name);if (res != null && res is DataTemplate template){temp = template;}else{temp = new DataTemplate();FrameworkElementFactory element = null;if (items.Count == 0){element = new FrameworkElementFactory(typeof(TreeItemContentControl));element.SetValue(ContentControl.ContentProperty, new Binding(name));}else{element = new FrameworkElementFactory(typeof(TreeGridCell));element.SetValue(ContentControl.ContentProperty, new Binding(name));}temp.VisualTree = element;}var col = new GridViewColumn{Width = 200,Header = title,CellTemplate = temp,};items.Add(col);}Columns = items;}#endregion#region Columns DependencyPropertypublic GridViewColumnCollection Columns{get { return (GridViewColumnCollection)GetValue(ColumnsProperty); }set { SetValue(ColumnsProperty, value); }}public static readonly DependencyProperty ColumnsProperty =DependencyProperty.Register("Columns", typeof(GridViewColumnCollection), typeof(TreeGrid),new PropertyMetadata(null, new PropertyChangedCallback(TreeGrid.OnColumnsPropertyChanged)));private static void OnColumnsPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e){if (obj is TreeGrid){(obj as TreeGrid).OnColumnsValueChanged();}}protected void OnColumnsValueChanged(){}#endregion#region RowHeight DependencyPropertypublic double RowHeight{get { return (double)GetValue(RowHeightProperty); }set { SetValue(RowHeightProperty, value); }}public static readonly DependencyProperty RowHeightProperty =DependencyProperty.Register("RowHeight", typeof(double), typeof(TreeGrid),new PropertyMetadata(30.0, new PropertyChangedCallback(TreeGrid.OnRowHeightPropertyChanged)));private static void OnRowHeightPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e){if (obj is TreeGrid){(obj as TreeGrid).OnRowHeightValueChanged();}}protected void OnRowHeightValueChanged(){}#endregion#region ShowCellBorder DependencyPropertypublic bool ShowCellBorder{get { return (bool)GetValue(ShowCellBorderProperty); }set { SetValue(ShowCellBorderProperty, value); }}public static readonly DependencyProperty ShowCellBorderProperty =DependencyProperty.Register("ShowCellBorder", typeof(bool), typeof(TreeGrid),new PropertyMetadata(false, new PropertyChangedCallback(TreeGrid.OnShowCellBorderPropertyChanged)));private static void OnShowCellBorderPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e){if (obj is TreeGrid){(obj as TreeGrid).OnShowCellBorderValueChanged();}}protected void OnShowCellBorderValueChanged(){}#endregion#region IconStroke DependencyPropertypublic Brush IconStroke{get { return (Brush)GetValue(IconStrokeProperty); }set { SetValue(IconStrokeProperty, value); }}public static readonly DependencyProperty IconStrokeProperty =DependencyProperty.Register("IconStroke", typeof(Brush), typeof(TreeGrid),new PropertyMetadata(new SolidColorBrush(Colors.LightGray), new PropertyChangedCallback(TreeGrid.OnIconStrokePropertyChanged)));private static void OnIconStrokePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e){if (obj is TreeGrid){(obj as TreeGrid).OnIconStrokeValueChanged();}}protected void OnIconStrokeValueChanged(){}#endregion#region CellBorderBrush DependencyPropertypublic Brush CellBorderBrush{get { return (Brush)GetValue(CellBorderBrushProperty); }set { SetValue(CellBorderBrushProperty, value); }}public static readonly DependencyProperty CellBorderBrushProperty =DependencyProperty.Register("CellBorderBrush", typeof(Brush), typeof(TreeGrid),new PropertyMetadata(new SolidColorBrush(Colors.LightGray), new PropertyChangedCallback(TreeGrid.OnCellBorderBrushPropertyChanged)));private static void OnCellBorderBrushPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e){if (obj is TreeGrid){(obj as TreeGrid).OnCellBorderBrushValueChanged();}}protected void OnCellBorderBrushValueChanged(){}#endregionprotected override DependencyObject GetContainerForItemOverride(){return new TreeGridItem();}protected override bool IsItemItsOwnContainerOverride(object item){return item is TreeGridItem;}protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e){base.OnItemsChanged(e);}}public class TreeGridItem : TreeViewItem{public event EventHandler IconStateChanged;static TreeGridItem(){DefaultStyleKeyProperty.OverrideMetadata(typeof(TreeGridItem), new FrameworkPropertyMetadata(typeof(TreeGridItem)));}public TreeGridItem(){this.DataContextChanged += TreeGridItem_DataContextChanged;}private void TreeGridItem_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e){if (DataContext != null && DataContext is TreeItemData treeData){this.SetBinding(IsExpandedProperty, new Binding("IsExpanded") { Source = treeData, Mode = BindingMode.TwoWay });}}protected override void OnVisualParentChanged(DependencyObject oldParent){base.OnVisualParentChanged(oldParent);}protected override DependencyObject GetContainerForItemOverride(){return new TreeGridItem();}protected override bool IsItemItsOwnContainerOverride(object item){return item is TreeGridItem;}}/** https://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Controls/GridViewRowPresenter.cs,ace7d38fc902993d* GridViewRow里的每个元素,增加了一个默认的Margin,这样在设置边框的时候会比较麻烦,在运行时去掉*/public class TreeGridCell : ContentControl{static TreeGridCell(){DefaultStyleKeyProperty.OverrideMetadata(typeof(TreeGridCell), new FrameworkPropertyMetadata(typeof(TreeGridCell)));}public TreeGridCell(){Loaded += TreeGridCell_Loaded;}private void TreeGridCell_Loaded(object sender, RoutedEventArgs e){Loaded -= TreeGridCell_Loaded;var p = VisualTreeHelper.GetParent(this);if (p != null && p is FrameworkElement f && f.Margin.Left > 0){f.Margin = new Thickness(0);}}}public static class TreeHelper{public static T FindParent<T>(this DependencyObject obj){var p = VisualTreeHelper.GetParent(obj);if (p == null){return default(T);}if (p is T tt){return tt;}return FindParent<T>(p);}public static T FindTreeResource<T>(this FrameworkElement obj, string key){if (obj == null){return default(T);}var r = obj.TryFindResource(key);if (r == null){r = Application.Current.TryFindResource(key);}if (r != null && r is T t){return t;}var p = FindParent<FrameworkElement>(obj);if (p != null){return FindTreeResource<T>(p, key);}return default(T);}}
}
3.TreeGrid.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="clr-namespace:TreeView.TreeDataGrid.Controls"><SolidColorBrush x:Key="TreeIconStroke" Color="GreenYellow" /><Style x:Key="TreeGridItemStyle" TargetType="{x:Type local:TreeGridItem}"><Setter Property="Foreground" Value="Black"/><Setter Property="Background" Value="Transparent"/><Setter Property="IsExpanded" Value="True"/><Setter Property="BorderBrush" Value="Wheat"/><Setter Property="BorderThickness" Value="0,0,0,1"/><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type local:TreeGridItem}"><StackPanel><Border Name="Bd"Background="Transparent"BorderBrush="{TemplateBinding BorderBrush}"Padding="{TemplateBinding Padding}"><GridViewRowPresenter x:Name="PART_Header" Content="{TemplateBinding Header}" Columns="{Binding Path=Columns,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:TreeGrid}}" /></Border><ItemsPresenter x:Name="ItemsHost" /></StackPanel><ControlTemplate.Triggers><Trigger Property="IsExpanded" Value="false"><Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed"/></Trigger><MultiTrigger><MultiTrigger.Conditions><Condition Property="HasHeader" Value="false"/><Condition Property="Width" Value="Auto"/></MultiTrigger.Conditions><Setter TargetName="PART_Header" Property="MinWidth" Value="75"/></MultiTrigger><MultiTrigger><MultiTrigger.Conditions><Condition Property="HasHeader" Value="false"/><Condition Property="Height" Value="Auto"/></MultiTrigger.Conditions><Setter TargetName="PART_Header" Property="MinHeight" Value="19"/></MultiTrigger><MultiTrigger><!--移动变色--><MultiTrigger.Conditions><Condition Property="IsFocused" Value="False"/><Condition SourceName="Bd" Property="IsMouseOver" Value="true"/></MultiTrigger.Conditions><Setter Property="Background" Value=" red" TargetName="Bd"/></MultiTrigger><Trigger Property="IsSelected" Value="true"><!--选中的背景颜色--><Setter TargetName="Bd" Property="Background" Value="YellowGreen"/><!--<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>--><Setter Property="Foreground" Value="Red"/></Trigger><!--隔行换色--><!--<Trigger Property="AlternationIndex" Value="0" ><Setter TargetName="Bd" Property="Background" Value="blue" /></Trigger><Trigger Property="AlternationIndex" Value="2" ><Setter TargetName="Bd" Property="Background" Value="black" /></Trigger>--><!--<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=local:TreeGrid}, Path=Columns.Count }" Value="0"><Setter TargetName="Bd" Property="Background" Value="#FFD3D3D3"/></DataTrigger><DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=local:TreeGrid}, Path=Columns.Count}" Value="2"><Setter TargetName="Bd" Property="Background" Value="#FFE6E6E6"/></DataTrigger>--><MultiTrigger><MultiTrigger.Conditions><Condition Property="IsSelected" Value="true"/><Condition Property="IsSelectionActive" Value="false"/></MultiTrigger.Conditions><Setter TargetName="Bd" Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/><Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/></MultiTrigger><Trigger Property="IsEnabled" Value="false"><Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter><Style.Triggers><!--隔行换色--><Trigger Property="AlternationIndex" Value="0" ><Setter Property="Background" Value="#e7e7e7" /></Trigger><Trigger Property="AlternationIndex" Value="1" ><Setter Property="Background" Value="#f2f2f2" /></Trigger></Style.Triggers></Style><Style TargetType="{x:Type local:TreeGridItem}" BasedOn="{StaticResource TreeGridItemStyle}"/><Style TargetType="{x:Type local:TreeGridCell}"><Setter Property="HorizontalContentAlignment" Value="Center"/><Setter Property="VerticalContentAlignment" Value="Center"/><Setter Property="BorderBrush" Value="Red"/><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type local:TreeGridCell}"><Border x:Name="CellBorder" Margin="0,0,-0.5,0"Background="{TemplateBinding Background}"BorderBrush="Red"BorderThickness="0,0,0,1"><ContentControl Content="{TemplateBinding Content}"ContentTemplate="{TemplateBinding ContentTemplate}"HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"VerticalAlignment="{TemplateBinding VerticalContentAlignment}"SnapsToDevicePixels="True"/></Border><!--BorderBrush="Red"下划线颜色--><!--<ControlTemplate.Triggers><DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:TreeGrid},Path=ShowCellBorder}" Value="true"><Setter TargetName="CellBorder" Property="BorderBrush" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:TreeGrid},Path=CellBorderBrush}" /></DataTrigger></ControlTemplate.Triggers>--></ControlTemplate></Setter.Value></Setter></Style><Style TargetType="{x:Type local:TreeGrid}"><Setter Property="IconStroke" Value="{StaticResource TreeIconStroke}"/><Setter Property="ItemContainerStyle" Value="{StaticResource {x:Type local:TreeGridItem}}"/><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type local:TreeGrid}"><Border Background="{TemplateBinding Background}"BorderBrush="{TemplateBinding BorderBrush}"BorderThickness="0"><!--最大边框--><DockPanel><!--标题栏--><GridViewHeaderRowPresenter IsHitTestVisible="False" Columns="{TemplateBinding Columns}" Height="{TemplateBinding RowHeight}" DockPanel.Dock="Top" ></GridViewHeaderRowPresenter><ItemsPresenter /></DockPanel></Border></ControlTemplate></Setter.Value></Setter></Style>
</ResourceDictionary>
4.代码很多,最终的源码格式
需要源码请联系我。
本文来源:
WPF组合控件TreeView+DataGrid之TreeView封装-CSDN博客
相关文章:

WPF组合控件TreeView+DataGrid之TreeView封装
(关注博主后,在“粉丝专栏”,可免费阅读此文) wpf的功能非常强大,很多控件都是原生的,但是要使用TreeViewDataGrid的组合,就需要我们自己去封装实现。 我们需要的效果如图所示&#x…...
redisson 哨兵模式配置
背景:项目redis由集群改为哨兵模式,漏洞扫描未授权访问漏洞(CNVD-2019-21763),要求对redis哨兵也设置密码,redisson依赖版本为3.11.5 spring-boot版本为2.1.13。 redisson依赖升级 <dependency>&l…...
免费的ChatGPT分享
免费的ChatGPT 以下是一些免费的ChatGPT平台和工具: 零声教学AI助手 零声教育内部使用的ChatGPT,提供智能对话和问题解答功能。 Ora.ai 一个可以自定义的AI聊天机器人,可以根据个人需求进行定制和训练。 ChatGPT 人工智能聊天机器人&a…...
C语言—每日选择题—Day54
指针相关博客 打响指针的第一枪:指针家族-CSDN博客 深入理解:指针变量的解引用 与 加法运算-CSDN博客 第一题 1. 存在int类型变量x,y,z,其对应值为x0x59,y0x39,z0x6E,则x * y z的值…...

先进制造身份治理现状洞察:从手动运维迈向自动化身份治理时代
在新一轮科技革命和产业变革的推动下,制造业正面临绿色化、智能化、服务化和定制化发展趋势。为顺应新技术革命及工业发展模式变化趋势,传统工业化理论需要进行修正和创新。其中,对工业化水平的判断标准从以三次产业比重标准为主回归到工业技…...
【密码学引论】密码协议
定义:两个或者两个以上参与者为了完成某一特定任务而采取的一系列执行步骤密码协议:Kerberos、IPSec、SSL、SET算法是低层次上的概念,而协议是高层次上的概念,协议建立在算法的基础上。所有密码协议都容易受中间人攻击,…...
利用快手的用户数据和精准营销提升电商平台用户转化率和销售额
一、快手用户数据的价值 快手作为国内领先的短视频平台,拥有庞大的用户群体和丰富的用户行为数据。这些数据包括用户的观看习惯、互动行为、兴趣偏好等,对于电商平台来说具有极高的商业价值。通过分析这些数据,电商平台可以深入了解用户需求…...
Linux根目录下默认目录作用
在Linux操作系统中,根目录(/)下的默认目录一般用于不同用途的文件存放和系统管理。以下是一些常见的默认目录及其用途: /bin:该目录存放系统的基本命令和可执行文件,如ls、cp、mv等。这些命令可供系统用户…...

国产Type-C接口逻辑协议芯片:Type-C显示器芯片方案
产品介绍 双Type-C盲插选型: LDR6282 PD3.0认证协议芯片,USB-IF TID号:212 支持iic,USB转UART,CC升级方式,多年市场验证,显示器市场出货量,显示器大厂采用兼容性NO.1。采用QFN32 5*…...

uniapp如何原生app-云打包
首先第一步,需要大家在HBuilder X中找到一个项目,然后呢在找到上面的发行选项 发行->原生App-云打包 选择完该选中的直接大包就ok。 大包完毕后呢,会出现一个apk包,这是后将这个包拖动发给随便一个人就行了。 然后接收到的那…...
分布式编译distcc
工程代码编译速度太慢,决定采用分布式编译来提高编译速度. distcc ,请参考https://www.distcc.org/ 安装 我用的distcc的版本是distcc-3.2rc1, 下载源码,安装步骤如下: ./autogen.sh ./configure --disable-Werror --prefix/…...

Elasticsearch常见面试题
文章目录 1.简单介绍下ES?2.简单介绍当前可以下载的ES稳定版本?3.安装ES前需要安装哪种软件?4.请介绍启动ES服务的步骤?5.ES中的倒排索引是什么?6. ES是如何实现master选举的?7. 如何解决ES集群的脑裂问题8…...

solidity 重入漏洞
目录 1. 重入漏洞的原理 2. 重入漏洞的场景 2.1 msg.sender.call 转账 2.2 修饰器中调用地址可控的函数 1. 重入漏洞的原理 重入漏洞产生的条件: 合约之间可以进行相互间的外部调用 恶意合约 B 调用了合约 A 中的 public funcA 函数,在函数 funcA…...

【智能家电】东胜物联离在线语音方案为厨电企业赋能,实现厨房智能化控制
近年来,我国厨电市场蓬勃发展。据行业统计数据显示,至今年6月,市场规模已达356亿元,同比增长8.8%。随着数字科技、物联网和人工智能的兴起,厨电产品正在朝着更智能、多功能化的方向迅速发展。 为此厨电厂商正在积极布…...

3DMAX英文版怎么切换到中文版?
3DMAX英文换到中文版的方法 3dMax是专业三维建模、渲染和动画软件,它使你能够创建广阔的真实世界和各种高级设计。 -使用强大的建模工具为环境和景观注入活力。 -使用直观的纹理和着色工具创建精细的细节设计和道具。 -迭代并制作具有完全艺术控制的专业级渲染图…...

WEB渗透—PHP反序列化(八)
Web渗透—PHP反序列化 课程学习分享(课程非本人制作,仅提供学习分享) 靶场下载地址:GitHub - mcc0624/php_ser_Class: php反序列化靶场课程,基于课程制作的靶场 课程地址:PHP反序列化漏洞学习_哔哩…...
LeetCode——2415. 反转二叉树的奇数层
通过万岁!!! 题目:给你一个完全二叉树,然后将其奇数层进行反转。思路:这个题他都说了是奇数层了,那基本就是层序遍历了。但是存在两个问题,一个是如何判断奇数层,另外一…...

【Spring学习笔记】Spring 注解开发
Spring学习——注解开发 注解开发注解开发定义bean纯注解开发 Bean管理bean作用范围bean生命周期 依赖注入自动装配 第三方bean管理注解开发总结XML配置与注解配置比较 注解开发 注解开发定义bean 使用Component定义开发 Component("bookDao") public class BookD…...

【华为数据之道学习笔记】6-5数据地图的核心价值
数据供应者与消费者之间往往存在一种矛盾:供应者做了大量的数据治理工作、提供了大量的数据,但数据消费者却仍然不满意,他们始终认为在使用数据之前存在两个重大困难。 1)找数难 企业的数据分散存储在上千个数据库、上百万张物理表…...

JavaWeb笔记之JSP
一、引言 现有问题 在之前学习Servlet时,服务端通过Servlet响应客户端页面,有什么不足之处? 开发方式麻烦:继承父类、覆盖方法、配置Web.xml或注解。 代码修改麻烦:重新编译、部署、重启服务。 显示方式麻烦&#x…...

【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...

CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...

DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...

【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...