WPF教程二:理解WPF的布局系统和常用的Panel布局
WPF的布局系统
了解元素的测量和排列方式是理解布局的第一步。在测量(measure)阶段容器遍历所有子元素,并询问子元素它们所期望的尺寸。在排列(arrange)阶段,容器在合适的位置放置子元素。理论上布局就结束了。
所有的WPF布局容器都派生自System.Windows.Controls.Panel。Panel继承自FrameworkElement。 在Panel中有一个比较重要的属性是UIElementCollection 类型的Children属性,
UIElementCollection是一个有序的集合。我们可以使用继承自Panel的类来重写MeasureOverride(),ArrangeOverride()实现自定义面板。
常用的布局容器:
Border不是布局面板,但是经过几个大佬的提醒,用好他真的很重要,所以我就放在第一个了。
StackPanel: 堆栈面板,水平或垂直放置元素。
WrapPanel:可换行的行中放置元素,在水平方向上从左向右放置元素,换行后也是从左向右。在垂直方向上,从上到下放置元素,在切换列后也是从上到下。
DockPanel: 根据容器的整个边界调整元素。
Grid:在行列表格中排列元素。
UniformGrid:强制所有单元格具有相同尺寸。
Canvas:使用固定坐标绝对定位元素。
ScrollViewer:通过添加滚动条可以使当前过长布局内的内容纵向或者横向滚动。再有限的区域内可以通过滚动呈现更多的内容。
Border不是布局面板,但是经常与布局类的面板一起配合使用,所以先介绍Border。
border的主要作用是给元素添加边框,这个元素可以理解为一个布局面板,一个控件等等。他包含设置边框的2个属性,BorderBrush用来设置颜色,BorderThickness用来设置宽度。CornerRadius设置圆角。而Padding和Margin一个设置边框和里面元素的间距,一个设置边框和其他临近元素的间距。而Background则是设置border所有内容的颜色。
<Window x:Class="Layout.Views.BorderExample"
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:Layout.Views"
mc:Ignorable="d"
Title="BorderExample" Height="450" Width="300">
<StackPanel>
<Border Background="Bisque" BorderBrush="Coral" BorderThickness="3">
<Button Content="Button A" Width="120"/>
</Border>
<Border BorderBrush="Red" BorderThickness="3" Margin="5">
<Button Content="Button B"/>
</Border>
<Border BorderBrush="DarkRed" BorderThickness="3" Background="Red" Padding="5">
<Button Content="Button C"/>
</Border>
</StackPanel>
</Window>
以下是运行效果。尝试修改以下颜色或大小看一下边框效果、背景色效果、分析一下哪部分是按钮、哪部分背景色、哪部分是边框、是按照自己的思路看一下修改效果。学习编写代码千万不要着急,建议再基础部分尽量多的投入精力。让自己静下来。
1、StackPanel布局
StackPanel面板可以在单行或者单列以堆栈的形式排列子元素。默认情况下StackPanel面板按从上到下的顺序排列元素。如果不指定宽度、则默认宽度和StackPanel面板宽度一致,如果StackPanel宽度发生变化,则按钮也会拉伸以适应变化。而如果设置了宽度、就不会跟面板宽度变更发生变化。但是想要设计出自己想要的好看布局,还需要更多的元素,先看一个基本的例子。
<Window x:Class="Layout.Views.StackPanelExample"
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:Layout.Views"
mc:Ignorable="d"
Title="StackPanelExample" Height="350" Width="500">
<StackPanel x:Name="root_spanel" >
<Button Content="点我切换方向" Click="OrientationTranslator_Click"/>
<Button Content="点我添加元素到面板中" Click="AddElementToPanel_Click"/>
<Button x:Name="btn_FixedWidth" Content="点我手动设置宽度为120" Click="SetCurrentWidth_Click"/>
<Button Content="杜文龙加油一定要深入C#啊!!!"/>
</StackPanel>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes; namespace Layout.Views
{
/// <summary>
/// StackPanelExample.xaml 的交互逻辑
/// </summary>
public partial class StackPanelExample : Window
{
public StackPanelExample()
{
InitializeComponent();
} private void OrientationTranslator_Click(object sender, RoutedEventArgs e)
{
root_spanel.Orientation = root_spanel.Orientation == Orientation.Horizontal ? Orientation.Vertical : Orientation.Horizontal;
} private void AddElementToPanel_Click(object sender, RoutedEventArgs e)
{
Button btn = new Button();
btn.Content = "我是新添加的Button";
root_spanel.Children.Add(btn);
} private void SetCurrentWidth_Click(object sender, RoutedEventArgs e)
{
btn_FixedWidth.Width = 120;
}
}
}
StackPanel面板效果。
而在熟练以后往往需要更多的参数配合使用来设计更好的UI布局。后面会出模仿现在主流的网络客户端比如QQ、网易音乐、电脑管家等等的例子用于实践面板布局的设计。
以下是布局过程中常用的设置:
布局属性名称 | 注释 |
HorizontalAlignment | 子元素在水平方向的对其方式:有Center、Left、Right、Stretch |
VerticalAlignment | 子元素在垂直方向的对齐方式:有Center、Top、Bottom、Stretch |
Margin | 表示在元素的周围添加一定的空间。值类型是Thickness格式、支持顶部、底部、左边、右边设置间距。 |
MinWidth和MinHeight | 这2个属性是设置元素的最小宽高、如果一个元素超出了其他布局容器则元素被裁剪。 |
MaxWidth和MaxHeight | 设置元素的最大宽高、如果面板中即使有更多的区域可用,但是如果超出了Max就会等于Max |
Width和Height | 用于显示的设置元素的宽高、会重写HorizontalAlignment、VerticalAlignment设置的Stretch值、但不能超出MinWidth、MinHeight和MaxWidth、MaxHeight的设置范围。 |
你可以在刚才的StackPanel面板的代码中使用以上表格内的属性来测试以下会产生什么样的变化。这里只做介绍。练习一下。后续会有模仿的布局设计。
PS:注意观察控件被裁剪。在设计多语言的控件时、控件显示区域被裁剪或者超出是一个非常麻烦、但是没有技术含量的事情。因为可能有30多个国家需要适配。所以布局这章学好了,对于节省工作量很重要。
2、WrapPanel布局
WrapPanel面板可以一次排列一行或一列然后再换行继续排列,和StackPanel一样,可以通过设置Orientation属性来设置当前是以水平还是垂直来排列子元素。因为是根据窗体变化演示布局排列,这个只有XAML。
<Window x:Class="Layout.Views.WrapPanelExample"
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:Layout.Views"
mc:Ignorable="d"
Title="WrapPanelExample" Height="150" Width="400">
<WrapPanel>
<Button Content="代码搬砖了6年。"/>
<Button Content="做事情浮躁不得。"/>
<Button Content="写代码有不明白的地方就要搞明白他。"/>
<Button Content="可以多买点书,也可以多找点教程。"/>
<Button Content="但是一定要静下心。慢慢有一套自己的学习方法。"/>
</WrapPanel>
</Window>
3、DockPanel布局
DockPanel面板与StackPanel面板类似,但是DockPanel可以通过设置Dock附加属性设置子元素停靠的边。
Dock的值为Left、Right、Top、Bottom。通过设置子元素再DockPanel面板中的Dock属性。可以修改子元素再DockPanel面板内的位置。可以通过LastChildFill设置为true来告诉DockPanel面板使最后一个元素占满剩余控件。而设置的停靠顺序会影响布局结果。我们实际看一下。
<Window x:Class="Layout.Views.DockPanelExample"
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:Layout.Views"
mc:Ignorable="d"
Title="DockPanelExample" Height="450" Width="800">
<DockPanel LastChildFill="True">
<Button DockPanel.Dock="Top" Content="今天学习了吗?"/>
<Button DockPanel.Dock="Left" Content="今天写代码了?"/>
<Button DockPanel.Dock="Right" Content="随便放点东西"/>
<Button DockPanel.Dock="Right" VerticalAlignment="Center" Content="真的理解了吗?要不要再多敲几遍。"/>
<Button DockPanel.Dock="Bottom" Content="程序员不学习写代码,还能干什么呢?"/>
<Button DockPanel.Dock="Bottom" Content="程序员不学习写代码,还能干什么呢?"/> </DockPanel>
</Window>
这个DockPanel根据插入元素顺序的不一致。面板布局也会不一样。自己可以尝试玩一下。设计一些自己喜欢的。
4、Grid布局
Grid面板是把显示内容分割到不可见的行列网格中。通过设置行列和对应的宽高占比。来进行网格布局。 Grid布局再平时使用的比较多。大部分都是用来做布局的嵌套,设计外框各个部分的比例,然后再子元素中嵌套其他布局控件。来实现区域的划分。
在使用Grid面板时,需要用到一个叫做附加依赖项属性的参数。在布局相关的内容里不会去讲什么是附加依赖项属性,这个会在依赖项属性中去讲解,这里只有了解就行。因为这个针对于Grid布局来说是固定写法。
我们添加一个三行三列的Grid面板。Grid.RowDefinitions和Grid.ColumnDefinitions里面的内容是我们设置的Gird的行列数。各有3个,代表我们是一个三行三列的网格。我们没有设置宽高。就会默认为是等分的。
<Window x:Class="Layout.Views.GridPanelExample"
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:Layout.Views"
mc:Ignorable="d"
Title="GridPanelExample" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
</Grid>
</Window>
网格布局设计好之后。我们需要往里面放置内容。我们要使用Grid.Column、Grid.Row这2个附加依赖项属性来实现把Button放置到不同的网格中(还记得如果遇到不熟悉的知识鼠标点上他然后F12看详情吗。可以先尝试了解一下。但是要记得这章的主题是布局)。我们在每个网格中放置一个Button我们不设置Button的宽高,让他来填充满当前的网格容器,用于分析我们的网格布局。修改代码如下:
<Window x:Class="Layout.Views.GridPanelExample"
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:Layout.Views"
mc:Ignorable="d"
Title="GridPanelExample" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Grid.Row="0" Content="Button Row 1 Column 1"/>
<Button Grid.Column="1" Grid.Row="0" Content="Button Row 1 Column 2"/>
<Button Grid.Column="2" Grid.Row="0" Content="Button Row 1 Column 3"/>
<Button Grid.Column="0" Grid.Row="1" Content="Button Row 2 Column 1"/>
<Button Grid.Column="1" Grid.Row="1" Content="Button Row 2 Column 2"/>
<Button Grid.Column="2" Grid.Row="1" Content="Button Row 2 Column 3"/>
<Button Grid.Column="0" Grid.Row="2" Content="Button Row 3 Column 1"/>
<Button Grid.Column="1" Grid.Row="2" Content="Button Row 3 Column 2"/>
<Button Grid.Column="2" Grid.Row="2" Content="Button Row 3 Column 3"/>
</Grid>
</Window>
我们就在XAML的一个Grid的根节点下创建了9个Button,Grid.column和Grid.Row是附加依赖项熟悉,只对当前对象的上一级Grid生效。如果不生效请检查XAML的结构。
我们尝试运行代码。就会得到9个一样大小的Button。我们尝试拖动窗体大小。不管怎么拖动,应该都是等量变化的。
这次我们修改Grid的RowDefinition和ColumnDefinition的宽高。来使网格布局满足一些常用的场景。比如我们要求左边一列宽度固定。右边一列以文本内容宽度适配,剩下的宽度区域都给中间的列。为了提高代码可读性,不建议省略Width="*"虽然都是一样的。
修改如下:
<Window x:Class="Layout.Views.GridPanelExample"
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:Layout.Views"
mc:Ignorable="d"
Title="GridPanelExample" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="140"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Grid.Row="0" Content="Button Row 1 Column 1"/>
<Button Grid.Column="1" Grid.Row="0" Content="Button Row 1 Column 2"/>
<Button Grid.Column="2" Grid.Row="0" Content="Button Row 1 Column 3 ces"/>
<Button Grid.Column="0" Grid.Row="1" Content="Button Row 2 Column 1"/>
<Button Grid.Column="1" Grid.Row="1" Content="Button Row 2 Column 2"/>
<Button Grid.Column="2" Grid.Row="1" Content="Button Row 2 Column 3 ces"/>
<Button Grid.Column="0" Grid.Row="2" Content="Button Row 3 Column 1"/>
<Button Grid.Column="1" Grid.Row="2" Content="Button Row 3 Column 2"/>
<Button Grid.Column="2" Grid.Row="2" Content="Button Row 3 Column 3 ces"/>
</Grid>
</Window>
我们尝试拖动整个窗体的大小,我们就会发现窗体按照我们预想的方式在改变每列Button布局的大小。可以按照自己的思路尝试修改这些代码然后跑起来看看会有什么样的影响。主要是理解网格布局。效果如下:
如果控件超出了布局的宽度或高度那么对应的内容就会被裁剪。在这里可以尝试多玩一下这个布局控件。看看他的变化,加深理解。尝试在Grid的属性上F12跳转看看还有哪些其他属性可以设置。
UseLayoutRounding属性是起什么作用的?Grid.RowSpan. Grid.ColumnSpan都起什么作用。可以尝试写一下。调试一下。GridSplitter没有讲,项目中我好像没要用到过。
PS: 等你实验完毕之后思考一下,再选择布局容器时,怎么能再得到正确布局的基础上使用合适的布局容器。Grid和StackPanel我们都学过了。
5、UniformGrid:
UniformGrid面板的特点是每个单元格始终保持一致的大小。通过设置行列数量来分割布局。元素通过放入的前后顺序被分配到不同的位置。这个再某些特定场景配合数据虚拟化和列表虚拟化使用的还是比较多的。效果图就不贴了。可以自己跑起来试一下。
<Window x:Class="Layout.Views.UniformGridExample"
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:Layout.Views"
mc:Ignorable="d"
Title="UniformGridExample" Height="450" Width="800">
<UniformGrid Columns="2" Rows="2">
<Button Content="Button A"/>
<Button Content="Button B"/>
<Button Content="Button C"/>
<Button Content="Button D"/>
</UniformGrid>
</Window>
6、Canvas:
Canvas是一个基于坐标的布局面板。他主要用于构建图形工具的绘图、Canvas知识再指定的位置放置子元素。并且子元素要提供精确的尺寸。再Canvas中需要设置Canvas.Left和Canvas.Top属性。用来设置相对于原点的left和top。
也可以使用Canvas.Right和Canvas.Bottom。但是Canvas.left和Right不能同时使用,Canvas.Top和Canvas.Bottom也不能同时使用。使用Panel.ZIndex来设置子元素的层级关系。
<Window x:Class="Layout.Views.CanvasPanelExample"
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:Layout.Views"
mc:Ignorable="d"
Title="CanvasPanelExample" Height="450" Width="800">
<Canvas>
<Button Content="Button A" Canvas.Left="10" Canvas.Top="10" Panel.ZIndex="2"/>
<Button Content="Button B" Canvas.Left="110" Canvas.Top="100"/>
<Button Content="Button C" Canvas.Left="20" Canvas.Top="3" Panel.ZIndex="1"/>
</Canvas>
</Window>
效果图如下:Button A和Button C的重叠关系使用Panel.ZIndex来设置。
7、ScrollViewer
如果要再一个比较小的区域内显示特别多的内容。就需要使用ScrollViewer来进行横向或纵向滚动了。但是再实际使用过程中往往配合数据虚拟化和列表虚拟化来实现支持更多内容的滚动效果。不然如果内容一旦特别多。ScrollViewer下的内容又特别长。每次滚动都会触发布局的重新测量和排列。如果不使用虚拟化,会全部重新计算所有的布局元素,会特别卡。导致使用困难。最后一个例子拉,这篇博客来来回回改了3天多。最后用一个ScroolViewer窗体结束这个DEMO拉。
目前常用的布局面板就这么多,本来还写了个TabPanel结果等博客写到这里的时候,发现这个TabPanel是TabControl重写样式的时候,用于修改TabItem显示样式的。我就删掉了关于TabControl的相关内容。
我创建了一个C#相关的交流群。用于分享学习资料和讨论问题。欢迎有兴趣的小伙伴:QQ群:542633085
WPF教程二:理解WPF的布局系统和常用的Panel布局的更多相关文章
- WPF教程二:布局之StackPanel面板
应用程序界面设计中,合理的元素布局至关重要,它可以方便用户使用,并将信息清晰合理地展现给用户.WPF提供了一套功能强大的工具-面板(Panel),来控制用户界面的布局.你可以使用这些面板控件来排布元素 ...
- MySQL8.0数据库基础教程(二)-理解"关系"
1 SQL 的哲学 形如 Linux 哲学一切都是文件,在 SQL 领域也有这样一条至理名言 一切都是关系 2 关系数据库 所谓关系数据库(Relational database)是创建在关系模型基础 ...
- WPF布局系统[转]
转自:http://www.cnblogs.com/niyw/archive/2010/10/31/1863908.html前言 前段时间忙了一阵子Google Earth,这周又忙了一阵子架构师论文 ...
- WPF教程十二:了解自定义控件的基础和自定义无外观控件
这一篇本来想先写风格主题,主题切换.自定义配套的样式.但是最近加班.搬家.新租的房子打扫卫生,我家宝宝6月中旬要出生协调各种的事情,导致了最近精神状态不是很好,又没有看到我比较喜欢的主题风格去模仿的, ...
- WPF系列教程——(二)使用Prism实现MVVM设计模式 - 简书
原文:WPF系列教程--(二)使用Prism实现MVVM设计模式 - 简书 本文假设你已经知道MVVM设计模式是什么,所以直接进入正题,今天我们就用Prism来实现WPF的MVVM设计模式,百度上关于 ...
- WPF教程九:理解WPF中的对象资源
在WPF中,所有继承自FrameworkElement的元素都包含一个Resources属性,这个属性就是我们这篇要讲的资源. 这一篇讲解的资源是不是上一篇的程序集资源(那个是在编译过程中打包到程序集 ...
- CSS Grid基于网格的二维布局系统(详细教程)
.grid-wrap{ display: inline-flex; padding: 20px; background: #f4f4f4; word-break: initial; } .handle ...
- WPF教程六:理解WPF中的隧道路由和冒泡路由事件
WPF中使用路由事件升级了传统应用开发中的事件,在WPF中使用路由事件能更好的处理事件相关的逻辑,我们从这篇开始整理事件的用法和什么是直接路由,什么是冒泡路由,以及什么是隧道路由. 事件最基本的用法 ...
- WPF教程:依赖属性
一.什么是依赖属性 依赖属性就是一种自己可以没有值,并且可以通过绑定从其他数据源获取值.依赖属性可支持WPF中的样式设置.数据绑定.继承.动画及默认值. 将所有的属性都设置为依赖属性并不总是正确的解决 ...
随机推荐
- Spring AOP 用法浅谈(Day_18)
当你这一天没有在进步,那你就是在退步! [简述] Aspect Oriented Programming :面向切面编程 所谓面向切面编程,是一种通过预编译和运行期动态代理的方式实现在不修改源代码的情 ...
- Java注解类型(@Annotation)
简述 注解本质是一个继承了Annotation的特殊接口,其具体实现类是Java运行时生成的动态代理类.而我们通过反射获取注解时,返回的是Java运行时生成的动态代理对象$Proxy1.通过代理对象调 ...
- 【无人机航空摄影测量精品教程】目录:摄影测量、Pix4d、EPS、CC、PhotoScan项目化作业流程及注意事项汇总
目录 1. 专栏简介 2. 专栏地址 3. 专栏目录 1. 专栏简介 该专栏为目前最为热门的无人机航测内外业项目,主要内容包括:无人机航测外业作业流程(像控点布设.航线规划.仿地飞行.航拍)和内业数据 ...
- 昇腾AI 软硬件全栈平台
昇腾AI 软硬件全栈平台
- Mask-RCNN技术解析
Mask-RCNN技术解析 MaskR-CNN 论文链接:https://arxiv.org/pdf/1703.06870.pdf 代码链接:https://github.com/CharlesSha ...
- 编译原理-DFA的化简(最小化)
对于给定的DFA M,寻找一个状态数比M小的DFA M'使得L(M)=L(M') 1.状态的等价性: 假设s和t为M的两个状态 ①若分别从状态s和状态t出发都能读出某个字α而停止于终态,则 ...
- 想玩转JAVA高并发,这些概念你必须懂
高并发高并发 它是互联网分布式系统架构设计中必须考虑的因素之一,通常是指,保证系统能够同时并行化处理海量请求 同步和异步 同步:发送一个请求,等待返回,然后再发送下一个请求.提交请求 -> 等待 ...
- 【模板】map入门
map 在数据特别庞大,数组已经满足不了的某些情况下codevs p1230,可以用上map; 我们可以将map容器作为一个有序的映射表,看作为一个下表可以是任意类型的数组: map是一个红黑树,单次 ...
- SpringBoot实战:10分钟快速搞定环境
什么是 springboot Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程. 该框架使用了特定的方式来进行配置,从而使开发人 ...
- 通过AI识图判断图片是否为小票
先在百度智能云中创建一个应用加入以下标记功能(没有智能云账号可以去创建一个,创建应用也都是些基本操作) 本次只用到标记的功能. 此功能在图像识别下面. 创建应用后,页面会出现平台分配的密钥:API K ...