WPF TreeView实现固定表头

news/2024/12/15 13:54:44/文章来源:https://www.cnblogs.com/lisghxfdfgh/p/18607923

1、在WPF中TreeView默认不支持固定表头的我们可以修改样式实现固定表头

  新建一个TreeListView类 然后继承TreeView代码如下

public class TreeListView : TreeView,IDisposable{public TreeListView(){//this.Loaded += TreeListView_Loaded;//this.SizeChanged += TreeListView_SizeChanged;//SourceUpdated += TreeListView_SourceUpdated;
        }private void TreeListView_SourceUpdated(object sender, System.Windows.Data.DataTransferEventArgs e){}double fixedColumnsWidth = 0;//int resizableColumnCount = 0;List<int> resizableColumnCount=new List<int>();GridViewHeaderRowPresenter gridViewHeaderRowPresenter;bool shub=false;private void TreeListView_SizeChanged(object sender, SizeChangedEventArgs e){fixedColumnsWidth = 0;var treeListView = sender as TreeListView; // 将 DependencyObject 转换为具体类型if (treeListView != null){double wh = treeListView.ActualWidth;for (int i = 0;i < treeListView.Columns.Count; i++){if (treeListView.Columns[i].Width > 0){if (resizableColumnCount.Contains(i)==false)fixedColumnsWidth += treeListView.Columns[i].Width;}else{if (resizableColumnCount.Any() == false)resizableColumnCount.Add(i);}}// 计算剩余空间double remainingWidth = wh - fixedColumnsWidth;// 如果有可调整宽度的列,将剩余空间均分给它们if (resizableColumnCount.Any()){double widthPerResizableColumn = remainingWidth / resizableColumnCount.Count;foreach (int i in resizableColumnCount){if (resizableColumnCount.Contains(i)){treeListView.Columns[i] .Width= widthPerResizableColumn;}}}}}private void TreeListView_Loaded(object sender, RoutedEventArgs e){gridViewHeaderRowPresenter=  this.Template.FindName("HeaderPresenter", this) as GridViewHeaderRowPresenter;if(gridViewHeaderRowPresenter != null ){gridViewHeaderRowPresenter.PreviewMouseLeftButtonDown += GridViewHeaderRowPresenter_PreviewMouseLeftButtonDown;gridViewHeaderRowPresenter.PreviewMouseMove += GridViewHeaderRowPresenter_PreviewMouseMove;gridViewHeaderRowPresenter.PreviewMouseLeftButtonUp += GridViewHeaderRowPresenter_PreviewMouseLeftButtonUp;}}private void GridViewHeaderRowPresenter_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e){shub=false;}private void GridViewHeaderRowPresenter_PreviewMouseMove(object sender, MouseEventArgs e){if (shub){//var d=  e.GetPosition(gridViewHeaderRowPresenter);//  // 找到当前被点击的列//  var hitTestResult = VisualTreeHelper.HitTest(gridViewHeaderRowPresenter, d);//  if (hitTestResult != null)//  {//      // 获取被点击的列标题//      var columnHeader = hitTestResult.VisualHit as GridViewColumn;//      if (columnHeader != null)//      {//          var gridView = (GridView)gridViewHeaderRowPresenter.DataContext;//          var columns = gridView.Columns;//          // 检查是否是最后一列//          //if (columnHeader.c == columns.Last())//          //{//          //    // 禁用拖动行为//          //    e.Handled = true;//          //}//      }//  }
            }}private void GridViewHeaderRowPresenter_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e){shub = true;}protected override System.Windows.DependencyObjectGetContainerForItemOverride(){return new TreeListViewItem();}protected override boolIsItemItsOwnContainerOverride(object item){return item is TreeListViewItem;}/// <summary>/// Gets or sets the collection of System.Windows.Controls.GridViewColumn /// objects that is defined for this TreeListView./// </summary>public GridViewColumnCollection Columns{get { return (GridViewColumnCollection)GetValue(ColumnsProperty); }set { SetValue(ColumnsProperty, value); }}// Using a DependencyProperty as the backing store for Columns.  This enables animation, styling, binding, etc...public static readonly System.Windows.DependencyProperty ColumnsProperty =System.Windows.DependencyProperty.Register("Columns", typeof(GridViewColumnCollection),typeof(TreeListView),new PropertyMetadata(OnColumnsChanged));////public Command PreviewMouseLeftButtonDownl//{//    get { return (Command)GetValue(PreviewMouseLeftButtonDownlProperty); }//    set { SetValue(PreviewMouseLeftButtonDownlProperty, value); }//}//// Using a DependencyProperty as the backing store for PreviewMouseLeftButtonDownl.  This enables animation, styling, binding, etc...//public static readonly DependencyProperty PreviewMouseLeftButtonDownlProperty =//    DependencyProperty.Register("PreviewMouseLeftButtonDownl", typeof(Command), typeof(GridViewColumnCollection), new PropertyMetadata(PreviewMouseLeftButtonDownlcleck));//private static void PreviewMouseLeftButtonDownlcleck(DependencyObject d, DependencyPropertyChangedEventArgs e)//{//}private static void OnColumnsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){// 在此处理属性更改的逻辑var treeListView = d as GridViewHeaderRowPresenter; // 将 DependencyObject 转换为具体类型if (treeListView != null){foreach (var columnHeader in treeListView.Columns){// (columnHeader.).PreviewMouseLeftButtonUp += ColumnHeader_PreviewMouseLeftButtonDown;//columnHeader.PreviewMouseMove += ColumnHeader_PreviewMouseMove;//columnHeader.PreviewMouseLeftButtonUp += ColumnHeader_PreviewMouseLeftButtonUp;
                }// 在此处添加您的处理逻辑,例如通知其他控件
            }}public void Dispose(){}}public class TreeListViewItem : TreeViewItem{/// <summary>/// Item's hierarchy in the tree/// </summary>public int Level{get{if (_level == -1){TreeListViewItem parent =ItemsControl.ItemsControlFromItemContainer(this)as TreeListViewItem;_level = (parent != null) ? parent.Level + 1 : 0;}return _level;}}protected override DependencyObjectGetContainerForItemOverride(){return new TreeListViewItem();}protected override bool IsItemItsOwnContainerOverride(object item){return item is TreeListViewItem;}private int _level = -1;}

 样式如下:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:convert="clr-namespace:TreeListViewSample.Converters"xmlns:local="clr-namespace:TreeListViewSample.Controls"><!--Converter for Indentation of items--><convert:LevelToIndentConverter x:Key="LevelIndentConverter" /><Style x:Key="ExpandCollapseToggleStyle" TargetType="{x:Type ToggleButton}"><Setter Property="Width" Value="19"/><Setter Property="Height" Value="13"/><Setter Property="Focusable" Value="False"/><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type ToggleButton}"><Border Width="19" Height="13" Background="Transparent"><Border Width="9" Height="9"BorderThickness="1"BorderBrush="#FF7898B5"CornerRadius="1"SnapsToDevicePixels="true"><Border.Background><LinearGradientBrush StartPoint="0,0" EndPoint="1,1"><LinearGradientBrush.GradientStops><GradientStop Color="White" Offset=".2"/><GradientStop Color="#FFC0B7A6" Offset="1"/></LinearGradientBrush.GradientStops></LinearGradientBrush></Border.Background><Path x:Name="ExpandPath"Margin="1,1,1,1"Fill="Black"Data="M 0 2 L 0 3 L 2 3 L 2 5 L 3 5 L 3 3 L 5 3 L 5 2 L 3 2 L 3 0 L 2 0 L 2 2 Z"/></Border></Border><ControlTemplate.Triggers><Trigger Property="IsChecked" Value="True"><Setter Property="Data" TargetName="ExpandPath" Value="M 0 2 L 0 3 L 5 3 L 5 2 Z"/></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter></Style><DataTemplate x:Key="CellTemplate_Name"><DockPanel><ToggleButton x:Name="Expander" Style="{StaticResource ExpandCollapseToggleStyle}" Margin="{Binding Path=Level,Converter={StaticResource LevelIndentConverter},RelativeSource={RelativeSource AncestorType={x:Type local:TreeListViewItem}}}"IsChecked="{Binding Path=IsExpanded,RelativeSource={RelativeSource AncestorType={x:Type local:TreeListViewItem}}}"ClickMode="Press"/><!--首列绑定值--><TextBlock Text="{Binding Name}"/></DockPanel><DataTemplate.Triggers><DataTrigger Binding="{Binding Path=HasItems,RelativeSource={RelativeSource AncestorType={x:Type local:TreeListViewItem}}}" Value="False"><Setter TargetName="Expander" Property="Visibility" Value="Hidden"/></DataTrigger></DataTemplate.Triggers></DataTemplate><!--<ImageBrush x:Key="gvHeaderBackground" ImageSource="/TreeListViewSample;component/Images/list_header_bk.png" />--><Style x:Key="gvColumnHeaderStyle" TargetType="{x:Type GridViewColumnHeader}"><Style.Setters><Setter Property="Height" Value="34" /><Setter Property="Background"><Setter.Value><LinearGradientBrush StartPoint="0,0" EndPoint="1,1"><GradientStop Color="LightBlue" Offset="0" /><GradientStop Color="Gray" Offset="1" /></LinearGradientBrush></Setter.Value></Setter></Style.Setters></Style><!--<GridViewColumnCollection x:Key="gvColumns"><GridViewColumn Header="姓名"CellTemplate="{StaticResource CellTemplate_Name}" Width="150" /><GridViewColumn Header="年龄" DisplayMemberBinding="{Binding Age}" Width="80" /><GridViewColumn Header="性别" DisplayMemberBinding="{Binding Sex}" Width="80" /><GridViewColumn Header="职务"DisplayMemberBinding="{Binding Duty}" Width="100" /></GridViewColumnCollection>--><!--交替行样式--><AlternationConverter x:Key="conBack"><SolidColorBrush>YellowGreen</SolidColorBrush><SolidColorBrush>SkyBlue</SolidColorBrush></AlternationConverter><Style TargetType="{x:Type local:TreeListViewItem}"><Setter Property="FontSize" Value="13" /><Setter Property="Background" Value="Transparent" /><Setter Property="SnapsToDevicePixels" Value="True" /><Setter Property="HorizontalContentAlignment" Value="Stretch" /><Setter Property="VerticalContentAlignment" Value="Center" /><Setter Property="IsSelected" Value="{Binding IsSelected}" /><Setter Property="IsExpanded" Value="{Binding IsExpanded}" /><Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Self},Path=(local:TreeListView.AlternationIndex),Converter={StaticResource conBack}}" /><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type local:TreeListViewItem}"><StackPanel><Border x:Name="outerBorder"BorderThickness="0,0,0,1"BorderBrush="#FFFFFFFD"Margin="0" Padding="0" Height="30"HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"SnapsToDevicePixels="True"><Border x:Name="innerBorder"BorderThickness="0,0,0,1"BorderBrush="#FFC6C6C6"Background="{TemplateBinding Background}"Padding="{TemplateBinding Padding}"HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"SnapsToDevicePixels="True"><GridViewRowPresenter x:Name="PART_Header"Content="{TemplateBinding Header}"         Columns="{Binding Columns,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:TreeListView}}"HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/></Border></Border><ItemsPresenter x:Name="ItemsHost" /></StackPanel><ControlTemplate.Triggers><!--<Trigger Property="local:TreeListView.AlternationIndex" Value="1">    Columns="{Binding Columns, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:TreeListView}"<Setter Property="Background" Value="#FFE1E4F7"></Setter></Trigger>--><Trigger Property="IsMouseOver" Value="true" SourceName="innerBorder"><Setter Property="Foreground" Value="White"/><Setter Property="Background" Value="#FFC66152" TargetName="innerBorder"/></Trigger><Trigger Property="IsSelected" Value="true"><!--<Setter TargetName="Bd" Property="Background"Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/><Setter Property="Foreground"Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>--><Setter Property="Foreground" Value="White"/><Setter Property="Background" Value="#FFC66152" TargetName="innerBorder"/></Trigger><Trigger Property="IsExpanded" Value="false"><Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed"/></Trigger><Trigger Property="IsEnabled" Value="false"><Setter Property="Foreground"Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/></Trigger><MultiTrigger><MultiTrigger.Conditions><Condition Property="IsSelected" Value="true"/><Condition Property="IsSelectionActive" Value="false"/></MultiTrigger.Conditions><Setter TargetName="innerBorder" Property="Background"Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/><Setter Property="Foreground"Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/></MultiTrigger><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></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter></Style><Style TargetType="{x:Type local:TreeListView}"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:Type local:TreeListView}"><!--Create a standard border around the 'TreeListView'.--><Border Padding="{TemplateBinding Padding}"BorderBrush="{TemplateBinding BorderBrush}"BorderThickness="{TemplateBinding BorderThickness}"Background="{TemplateBinding Background}"><!--ScrollViewer providing horizontal scrolling functionality for both, content and headers.--><!--<ScrollViewer HorizontalScrollBarVisibility="Auto" CanContentScroll="{TemplateBinding ScrollViewer.CanContentScroll}"VerticalScrollBarVisibility="Auto"  Focusable="False">--><DockPanel><!--The header row.  PreviewMouseLeftButtonDown="{Binding }" PreviewMouseMove=""  PreviewMouseLeftButtonUp=""--><GridViewHeaderRowPresenter DockPanel.Dock="Top" SnapsToDevicePixels="True" x:Name="HeaderPresenter"Columns="{Binding Columns,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:TreeListView}}"ColumnHeaderContainerStyle="{StaticResource gvColumnHeaderStyle}"></GridViewHeaderRowPresenter><!--ScrollViewer providing vertical scrolling Columns="{StaticResource gvColumns}"functionality for the content.--><ScrollViewer HorizontalScrollBarVisibility="Auto" CanContentScroll="{TemplateBinding ScrollViewer.CanContentScroll}"VerticalScrollBarVisibility="Auto"  Focusable="False"><!--ItemsPresenter containg the content.--><ItemsPresenter /></ScrollViewer></DockPanel><!--</ScrollViewer>--></Border></ControlTemplate></Setter.Value></Setter></Style><!--<Style TargetType="GridViewHeaderRowPresenter"><Setter Property="SnapsToDevicePixels" Value="True"/><Setter Property="Background" Value="LightBlue"/>--><!-- 修改背景颜色 --><!--<Setter Property="Foreground" Value="Black"/>--><!-- 修改字体颜色 --><!--<Setter Property="FontSize" Value="14"/>--><!-- 修改字体大小 --><!--<Setter Property="FontWeight" Value="Bold"/>--><!-- 修改字体粗细 --><!--<Setter Property="HorizontalContentAlignment" Value="Left"/><Setter Property="VerticalContentAlignment" Value="Center"/><Setter Property="Height" Value="30"/>--><!-- 修改行高 --><!--<Setter Property="Padding" Value="8"/>--><!-- 修改内边距 --><!--<Setter Property="Template"><Setter.Value><ControlTemplate TargetType="{x:TypeGridViewHeaderRowPresenter}"><GridViewHeaderRowPresenterColumns="{TemplateBindingGridView.ColumnHeaderContainerStyle}"Columns="{TemplateBindingGridView.Columns}"ColumnHeaderContextMenu="{TemplateBindingGridView.ColumnHeaderContextMenu}"ColumnHeaderToolTip="{TemplateBindingGridView.ColumnHeaderToolTip}"KeyboardNavigation.TabNavigation="Local"SnapsToDevicePixels="{TemplateBindingSnapsToDevicePixels}"/></ControlTemplate></Setter.Value></Setter></Style>-->
</ResourceDictionary>

添加测试数据的代码如下

namespace TreeListViewSample.ViewModels
{public class MainViewModel : ViewModelBase{private ObservableCollection<Staff> _StaffList = new ObservableCollection<Staff>();public ObservableCollection<Staff> StaffList{get { return _StaffList; }set{_StaffList = value;this.RaisePropertyChanged("StaffList");}}public MainViewModel(){for (int i = 0; i < 10000; i++){Staff staff = new Staff(){Name = "张三",Age = 30,Sex = "",Duty = "经理",IsExpanded = true};Staff staff2 = new Staff(){Name = "张三1",Age = 21,Sex = "",Duty = "员工",IsExpanded = true};Staff staff3 = new Staff(){Name = "张三11",Age = 21,Sex = "",Duty = "员工"};staff2.StaffList.Add(staff3);staff3 = new Staff(){Name = "张三22",Age = 21,Sex = "",Duty = "员工"};staff2.StaffList.Add(staff3);staff.StaffList.Add(staff2);staff2 = new Staff(){Name = "张三2",Age = 22,Sex = "",Duty = "员工"};staff.StaffList.Add(staff2);staff2 = new Staff(){Name = "张三3",Age = 23,Sex = "",Duty = "员工"};staff.StaffList.Add(staff2);StaffList.Add(staff);staff = new Staff(){Name = "李四",Age = 31,Sex = "",Duty = "副经理"};staff2 = new Staff(){Name = "李四1",Age = 24,Sex = "",Duty = "员工"};staff.StaffList.Add(staff2);staff2 = new Staff(){Name = "李四2",Age = 25,Sex = "",Duty = "员工"};staff.StaffList.Add(staff2);staff2 = new Staff(){Name = "李四3",Age = 26,Sex = "",Duty = "员工"};staff.StaffList.Add(staff2);StaffList.Add(staff);staff = new Staff(){Name = "王五",Age = 32,Sex = "",Duty = "组长"};staff2 = new Staff(){Name = "王五1",Age = 27,Sex = "",Duty = "员工"};staff.StaffList.Add(staff2);staff2 = new Staff(){Name = "王五2",Age = 28,Sex = "",Duty = "员工"};staff.StaffList.Add(staff2);StaffList.Add(staff);}        }public void ChangeNode1Value(){foreach (Staff staff in this.StaffList){staff.Age += 1;staff.Sex = staff.Sex == "" ? "" : "";}}public void ChangeNode2Value(){foreach (Staff staff in this.StaffList){foreach (Staff staff2 in staff.StaffList){staff2.Age += 1;staff2.Sex = staff2.Sex == "" ? "" : "";}}}}
}

最后 这里我们开启了虚拟化添加再多数据界面也不会卡顿

    <local:TreeListView x:Name="treeList" ScrollViewer.CanContentScroll="True"VirtualizingStackPanel.IsVirtualizing="True"VirtualizingStackPanel.VirtualizationMode="Recycling"Background="#FFE9E9E9" BorderBrush="#FF96DFFF"AlternationCount="2" ItemsSource="{Binding StaffList}"><local:TreeListView.ItemsPanel><ItemsPanelTemplate><VirtualizingStackPanel x:Name="ItemsHost" IsItemsHost="True" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" Height="Auto"/></ItemsPanelTemplate></local:TreeListView.ItemsPanel><local:TreeListView.Columns><GridViewColumnCollection><GridViewColumn Header="姓名" CellTemplate="{StaticResource CellTemplate_Name}" Width="200" ></GridViewColumn><GridViewColumn Header="年龄" DisplayMemberBinding="{Binding Age}" Width="80" /><GridViewColumn Header="性别" DisplayMemberBinding="{Binding Sex}" Width="80" /><GridViewColumn Header="职务"DisplayMemberBinding="{Binding Duty}" Width="150"/></GridViewColumnCollection></local:TreeListView.Columns><local:TreeListView.ItemTemplate><HierarchicalDataTemplate ItemsSource="{Binding StaffList}" /></local:TreeListView.ItemTemplate></local:TreeListView>

最后效果

 

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

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

相关文章

居家徒手健身

居家徒手健身 力竭组,组间歇2min,动作变形算力竭为一组 第一天:胸+三头 动作: 宽距俯卧撑6组(胸外延) 标准俯卧撑4组胸整体 钻石俯卧撑4组(胸中缝) 板凳臂屈伸4~8组(三头) 第二天:肩 +腿 动作: 折刀俯卧撑6~10组(肩中束) 腰间俯卧撑4~6组 (肩前束) 弹力绳深蹲6组…

个人网站建站日记-集成Markdown编辑器

一次偶然的机会,我体验的到了markdown的便捷,于是乎,我就着手给我的网站闲蛋博客社区集成了Markdown,现在可以自由的切换Markdown与富文本编辑的使用了。这里我特此分享记录下安装使用的过程。 一、安装Markdown编辑器 这里我采用的是md-editor-v3编辑器,目前看来还是很好…

arbitrum 资产桥合约

资产桥的作用 Rollup 的主要流程中,实际上不包含资产桥,也就是说即使没有资产桥,L2依然能正常运行但是此时L1与L2在数据上是完全独立的两条链,L1不理解L2上的数据(L1只保存L2压缩后的数据,不理解数据),L2上也不知道L1上发生了什么(只能拿到区块高度等一些基本信息)。完…

鸿蒙NEXT开发案例:经纬度距离计算

【引言】 在鸿蒙NEXT平台上,我们可以轻松地开发出一个经纬度距离计算器,帮助用户快速计算两点之间的距离。本文将详细介绍如何在鸿蒙NEXT中实现这一功能,通过简单的用户界面和高效的计算逻辑,为用户提供便捷的服务。 【环境准备】 • 操作系统:Windows 10 • 开发工具:De…

C语言中0为假,正数和负数均为真

001、[b20223040323@admin2 test]$ ls test.c [b20223040323@admin2 test]$ cat test.c #include <stdio.h>int main(void) {int i,j,k; ## 三个变量 负数、正数和0i = -5;j = 8;k = 0;if(i){puts("xxxx");}if(j){puts("yyyy");}if(k){puts(&qu…

2024-2025-1(20241321)《计算机基础与程序设计》第十二周学习总结

这个作业属于哪个课程 <班级的链接>(2024-2025-1-计算机基础与程序设计)这个作业要求在哪里 <作业要求的链接>(2024-2025-1计算机基础与程序设计第十二周作业)这个作业的目标 <深刻学习C语言,反思一周学习,温故知新>作业正文 ... 本博客链接https://www.…

Jmeter接口测试-图片验证码的识别

Jmeter接口测试-对图片验证码的识别Jmeter接口测试-对验证码的识别 ## 大概说一下思路,以及方法,我的接口接口的返回值是img/base64编码的,我采用的是OCR Server识别,获取返回值,图片保存到本地,再图片转码base64,之后携带数据请求OCR识别。(网上的办法是接口这种base6…

yolo导出,动态batch,固定图片尺寸

当使用export,dynamic=True时,batch和尺寸都是动态的。若想只有batch动态

如何在PbootCMS中实现自动清理runtime缓存?

要在PbootCMS中实现自动清理runtime缓存,可以按照以下步骤操作:编辑控制器文件:打开文件 /apps/home/controller/ExtLabelController.php。 找到以下代码:php// 测试扩展单个标签 private function test() {$this->content = str_replace({pboot:userip}, get_user_ip()…

如何修改自动清理脚本的清理间隔时间?

如果你想修改自动清理脚本的清理间隔时间,可以在控制器文件中调整 expire_time 的计算方式。以下是具体步骤:编辑控制器文件:打开文件 /apps/home/controller/ExtLabelController.php。 找到以下代码:php// 自动会话清理脚本 public function clean_session() {check_dir(R…

如果修改权限后仍然提示“会话目录写入权限不足”,应该如何处理?

如果您已经按照建议修改了PbootCMS相关目录的权限,但仍然收到“会话目录写入权限不足”的提示,可能是由于以下几个原因导致的:服务器配置问题:某些服务器可能有特殊的权限管理机制,例如SELinux或AppArmor。这些机制可能会限制Web服务器对某些目录的写入权限,即使您已经设…

帝国CMS灵动标签调用栏目内容排除某些栏目方法

使用灵动标签中的条件来排除特定栏目内容 示例代码:[e:loop={0,20,5,1,id not in(7,9,15,16),newstime DESC}] <a href="<?=$bqsr[titleurl]?>"><?=$bqr[title]?></a> [/e:loop]通过 id not in(7,9,15,16) 条件排除指定的栏目ID【遇到问…