[源码下载]

背水一战 Windows 10 (52) - 控件(集合类): ItemsControl - 自定义 ItemsControl, 自定义 ContentPresenter

作者:webabcd

介绍
背水一战 Windows 10 之 控件(集合类 - ItemsControl)

  • 自定义 ItemsControl(自定义 GirdView 使其每个 item 占用不同大小的空间)
  • 自定义 ContentPresenter 实现类似 GridViewItemPresenter 和 ListViewItemPresenter 的效果

示例
1、自定义 ItemsControl(自定义 GirdView 使其每个 item 占用不同大小的空间)
Controls/CollectionControl/ItemsControlDemo/MyItemsControlDemo.xaml

  1. <Page
  2. x:Class="Windows10.Controls.CollectionControl.ItemsControlDemo.MyItemsControlDemo"
  3. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  4. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  5. xmlns:local="using:Windows10.Controls.CollectionControl.ItemsControlDemo"
  6. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  7. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  8. mc:Ignorable="d">
  9.  
  10. <Page.Resources>
  11. <DataTemplate x:Key="ItemTemplate">
  12. <Grid Background="{Binding ColorValue}">
  13. <Grid Background="Black" VerticalAlignment="Top" Opacity="0.7">
  14. <TextBlock Text="{Binding ColorName}" />
  15. </Grid>
  16. </Grid>
  17. </DataTemplate>
  18. <Style x:Key="ItemContainerStyle" TargetType="GridViewItem">
  19. <Setter Property="VerticalContentAlignment" Value="Stretch" />
  20. <Setter Property="HorizontalContentAlignment" Value="Stretch" />
  21. <Setter Property="Margin" Value="0" />
  22. <Setter Property="Padding" Value="0" />
  23. </Style>
  24. <ItemsPanelTemplate x:Key="ItemsPanel">
  25. <VariableSizedWrapGrid MaximumRowsOrColumns="8" Orientation="Horizontal" ItemWidth="100" ItemHeight="100" />
  26. </ItemsPanelTemplate>
  27.  
  28. </Page.Resources>
  29.  
  30. <Grid Background="Transparent" Margin="10 0 10 10">
  31. <!--
  32. 使用 MyGridView 控件,其重写了 GridView 的 PrepareContainerForItemOverride() 方法,详见 MyGridView.cs
  33. -->
  34. <local:MyGridView x:Name="gridView" Width="812" VerticalAlignment="Top" HorizontalAlignment="Left"
  35. ItemTemplate="{StaticResource ItemTemplate}"
  36. ItemContainerStyle="{StaticResource ItemContainerStyle}"
  37. ItemsPanel="{StaticResource ItemsPanel}"
  38. IsItemClickEnabled="False"
  39. SelectionMode="None">
  40. </local:MyGridView>
  41. </Grid>
  42. </Page>

Controls/CollectionControl/ItemsControlDemo/MyItemsControlDemo.xaml.cs

  1. /*
  2. * ItemsControl - 集合控件(继承自 Control, 请参见 /Controls/BaseControl/ControlDemo/)
  3. * protected virtual void PrepareContainerForItemOverride(DependencyObject element, object item); - 为 item 准备 container 时
  4. * element - item 的 container
  5. * item - item
  6. *
  7. *
  8. * 本例用于演示如何使 GirdView 中的每个 item 占用不同大小的空间
  9. * 1、布局控件要使用 VariableSizedWrapGrid(利用其 RowSpan 和 ColumnSpan 来实现 item 占用不同大小的空间),需要注意的是其并非是虚拟化布局控件
  10. * 2、自定义 GridView,并重写 ItemsControl 的 protected override void PrepareContainerForItemOverride(DependencyObject element, object item) 方法
  11. * 然后设置每个 item 的 VariableSizedWrapGrid.RowSpan 和 VariableSizedWrapGrid.ColumnSpan
  12. */
  13.  
  14. using System;
  15. using System.Collections.Generic;
  16. using System.Linq;
  17. using Windows.UI;
  18. using Windows.UI.Xaml;
  19. using Windows.UI.Xaml.Controls;
  20. using Windows.UI.Xaml.Media;
  21. using System.Reflection;
  22.  
  23. namespace Windows10.Controls.CollectionControl.ItemsControlDemo
  24. {
  25. public sealed partial class MyItemsControlDemo : Page
  26. {
  27. public MyItemsControlDemo()
  28. {
  29. this.InitializeComponent();
  30.  
  31. BindData();
  32. }
  33.  
  34. private void BindData()
  35. {
  36. Random random = new Random();
  37.  
  38. // 获取 Windows.UI.Colors 的全部数据
  39. Type type = typeof(Colors);
  40. List<ColorModel> colors = type.GetRuntimeProperties() // GetRuntimeProperties() 在 System.Reflection 命名空间下
  41. .Select(c => new ColorModel
  42. {
  43. ColorName = c.Name,
  44. ColorValue = new SolidColorBrush((Color)c.GetValue(null)),
  45. ColSpan = random.Next(, ), // 此对象所占网格的列合并数
  46. RowSpan = random.Next(, ) // 此对象所占网格的行合并数
  47. })
  48. .ToList();
  49.  
  50. // 绑定数据
  51. gridView.ItemsSource = colors;
  52. }
  53. }
  54.  
  55. /// <summary>
  56. /// 用于数据绑定的对象
  57. /// </summary>
  58. public class ColorModel
  59. {
  60. public string ColorName { get; set; }
  61. public SolidColorBrush ColorValue { get; set; }
  62.  
  63. // 此对象所占的网格的列合并数
  64. public int ColSpan { get; set; }
  65. // 此对象所占的网格的行合并数
  66. public int RowSpan { get; set; }
  67. }
  68.  
  69. /// <summary>
  70. /// 自定义 GridView,重写 ItemsControl 的 protected override void PrepareContainerForItemOverride(DependencyObject element, object item) 方法
  71. /// 用于指定 GridView 的每个 item 所占网格的列合并数和行合并数
  72. /// </summary>
  73. public class MyGridView : GridView
  74. {
  75. protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
  76. {
  77. try
  78. {
  79. // 设置每个 item 的 VariableSizedWrapGrid.RowSpan 和 VariableSizedWrapGrid.ColumnSpan, 从而实现每个 item 占用不同大小的空间
  80. // 仅为演示用,由于这里的 ColSpan 和 RowSpan 都是随机计算的,所以可能会出现空白空间
  81.  
  82. dynamic dynamicItem = item;
  83. element.SetValue(VariableSizedWrapGrid.ColumnSpanProperty, dynamicItem.ColSpan);
  84. element.SetValue(VariableSizedWrapGrid.RowSpanProperty, dynamicItem.RowSpan);
  85. }
  86. catch (Exception ex)
  87. {
  88. var ignore = ex;
  89.  
  90. // 当有异常情况发生时(比如:item 没有 ColSpan 属性或 RowSpan 属性)
  91.  
  92. element.SetValue(VariableSizedWrapGrid.ColumnSpanProperty, );
  93. element.SetValue(VariableSizedWrapGrid.RowSpanProperty, );
  94. }
  95. finally
  96. {
  97. base.PrepareContainerForItemOverride(element, item);
  98. }
  99. }
  100. }
  101. }

2、自定义 ContentPresenter 实现类似 GridViewItemPresenter 和 ListViewItemPresenter 的效果
Controls/CollectionControl/ItemsControlDemo/MyItemPresenter.cs

  1. /*
  2. * 自定义 ContentPresenter 实现类似 GridViewItemPresenter 和 ListViewItemPresenter 的效果
  3. */
  4.  
  5. using System;
  6. using Windows.Foundation;
  7. using Windows.UI;
  8. using Windows.UI.Xaml;
  9. using Windows.UI.Xaml.Controls;
  10. using Windows.UI.Xaml.Media;
  11. using Windows.UI.Xaml.Media.Animation;
  12. using Windows.UI.Xaml.Shapes;
  13.  
  14. namespace Windows10.Controls.CollectionControl.ItemsControlDemo
  15. {
  16. class MyItemPresenter : ContentPresenter
  17. {
  18. Panel _container = null; // item 的容器(即在 DataTemplate 中定义的根元素,在示例 MyItemPresenterDemo.xaml 中用的是 Grid)
  19. Rectangle _pointerOverBorder = null; // 鼠标经过 item 时覆盖在 item 上的 rectangle
  20. Rectangle _focusVisual = null; // 选中 item 时覆盖在 item 上的 rectangle
  21.  
  22. Storyboard _pointerDownStoryboard = null; // 鼠标按下时的动画
  23. Storyboard _pointerUpStoryboard = null; // 鼠标抬起时的动画
  24.  
  25. public MyItemPresenter()
  26. : base()
  27. {
  28. base.Margin = new Thickness();
  29. }
  30.  
  31. // override OnApplyTemplate() - 应用控件模板时调用
  32. protected override void OnApplyTemplate()
  33. {
  34. base.OnApplyTemplate();
  35.  
  36. _container = (Panel)VisualTreeHelper.GetChild(this, );
  37. }
  38.  
  39. // override GoToElementStateCore() - VisualState 转换时调用(此方法仅在自定义 ContentPresenter 并将其应用于 GridView 或 ListView 的 ItemContainerStyle 时才会被调用)
  40. // stateName - VisualState 的名字
  41. // useTransitions - 是否使用 VisualTransition 过渡效果
  42. protected override bool GoToElementStateCore(string stateName, bool useTransitions)
  43. {
  44. base.GoToElementStateCore(stateName, useTransitions);
  45.  
  46. switch (stateName)
  47. {
  48. // 正常状态
  49. case "Normal":
  50. HidePointerOverVisuals();
  51. HideFocusVisuals();
  52. if (useTransitions)
  53. {
  54. StopPointerDownAnimation();
  55. }
  56. break;
  57.  
  58. // 选中状态
  59. case "Selected":
  60. case "PointerFocused":
  61. ShowFocusVisuals();
  62. if (useTransitions)
  63. {
  64. StopPointerDownAnimation();
  65. }
  66. break;
  67.  
  68. // 取消选中状态
  69. case "Unfocused":
  70. HideFocusVisuals();
  71. break;
  72.  
  73. // 鼠标经过状态
  74. case "PointerOver":
  75. ShowPointerOverVisuals();
  76. if (useTransitions)
  77. {
  78. StopPointerDownAnimation();
  79. }
  80. break;
  81.  
  82. // 鼠标点击状态
  83. case "Pressed":
  84. case "PressedSelected":
  85. if (useTransitions)
  86. {
  87. StartPointerDownAnimation();
  88. }
  89. break;
  90.  
  91. default: break;
  92. }
  93.  
  94. return true;
  95. }
  96.  
  97. private void StartPointerDownAnimation()
  98. {
  99. if (_pointerDownStoryboard == null)
  100. CreatePointerDownStoryboard();
  101.  
  102. _pointerDownStoryboard.Begin();
  103. }
  104.  
  105. private void StopPointerDownAnimation()
  106. {
  107. if (_pointerUpStoryboard == null)
  108. CreatePointerUpStoryboard();
  109.  
  110. _pointerUpStoryboard.Begin();
  111. }
  112.  
  113. private void ShowFocusVisuals()
  114. {
  115. if (!FocusElementsAreCreated())
  116. CreateFocusElements();
  117.  
  118. _focusVisual.Opacity = ;
  119. }
  120.  
  121. private void HideFocusVisuals()
  122. {
  123. if (FocusElementsAreCreated())
  124. _focusVisual.Opacity = ;
  125. }
  126.  
  127. private void ShowPointerOverVisuals()
  128. {
  129. if (!PointerOverElementsAreCreated())
  130. CreatePointerOverElements();
  131.  
  132. _pointerOverBorder.Opacity = ;
  133. }
  134.  
  135. private void HidePointerOverVisuals()
  136. {
  137. if (PointerOverElementsAreCreated())
  138. _pointerOverBorder.Opacity = ;
  139. }
  140.  
  141. private void CreatePointerDownStoryboard()
  142. {
  143. /*
  144. * 用这种方式为 item 实现鼠标按下的效果会报错(Attempted to read or write protected memory. This is often an indication that other memory is corrupt.),不知道为什么
  145. * PointerDownThemeAnimation pointerDownAnimation = new PointerDownThemeAnimation();
  146. * Storyboard.SetTarget(pointerDownAnimation, _container);
  147. * Storyboard pointerDownStoryboard = new Storyboard();
  148. * pointerDownStoryboard.Children.Add(pointerDownAnimation);
  149. */
  150.  
  151. DoubleAnimation da1 = new DoubleAnimation()
  152. {
  153. To = 0.9,
  154. Duration = TimeSpan.FromMilliseconds()
  155. };
  156. DoubleAnimation da2 = new DoubleAnimation()
  157. {
  158. To = 0.9,
  159. Duration = TimeSpan.FromMilliseconds()
  160. };
  161. Storyboard.SetTarget(da1, _container);
  162. Storyboard.SetTargetProperty(da1, "(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)");
  163. Storyboard.SetTarget(da2, _container);
  164. Storyboard.SetTargetProperty(da2, "(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)");
  165. if (!(_container.RenderTransform is TransformGroup))
  166. {
  167. TransformGroup Group = new TransformGroup();
  168. Group.Children.Add(new ScaleTransform());
  169. _container.RenderTransform = Group;
  170. _container.RenderTransformOrigin = new Point(0.5, 0.5);
  171. }
  172.  
  173. _pointerDownStoryboard = new Storyboard();
  174. _pointerDownStoryboard.Children.Add(da1);
  175. _pointerDownStoryboard.Children.Add(da2);
  176. _pointerDownStoryboard.Begin();
  177. }
  178.  
  179. private void CreatePointerUpStoryboard()
  180. {
  181. DoubleAnimation da1 = new DoubleAnimation()
  182. {
  183. To = ,
  184. Duration = TimeSpan.FromMilliseconds()
  185. };
  186. DoubleAnimation da2 = new DoubleAnimation()
  187. {
  188. To = ,
  189. Duration = TimeSpan.FromMilliseconds()
  190. };
  191. Storyboard.SetTarget(da1, _container);
  192. Storyboard.SetTargetProperty(da1, "(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)");
  193. Storyboard.SetTarget(da2, _container);
  194. Storyboard.SetTargetProperty(da2, "(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)");
  195. if (!(_container.RenderTransform is TransformGroup))
  196. {
  197. TransformGroup Group = new TransformGroup();
  198. Group.Children.Add(new ScaleTransform());
  199. _container.RenderTransform = Group;
  200. _container.RenderTransformOrigin = new Point(0.5, 0.5);
  201. }
  202.  
  203. _pointerUpStoryboard = new Storyboard();
  204. _pointerUpStoryboard.Children.Add(da1);
  205. _pointerUpStoryboard.Children.Add(da2);
  206. _pointerUpStoryboard.Begin();
  207. }
  208.  
  209. private void CreatePointerOverElements()
  210. {
  211. _pointerOverBorder = new Rectangle();
  212. _pointerOverBorder.IsHitTestVisible = false;
  213. _pointerOverBorder.Opacity = ;
  214. // 这里把颜色写死了,仅为演示用,实际写的时候要摘出来写成依赖属性
  215. _pointerOverBorder.Fill = new SolidColorBrush(Color.FromArgb(0x50, 0x50, 0x50, 0x50));
  216.  
  217. _container.Children.Insert(_container.Children.Count, _pointerOverBorder);
  218. }
  219.  
  220. private void CreateFocusElements()
  221. {
  222. _focusVisual = new Rectangle();
  223. _focusVisual.IsHitTestVisible = false;
  224. _focusVisual.Height = ;
  225. _focusVisual.VerticalAlignment = VerticalAlignment.Bottom;
  226. // 这里把颜色写死了,仅为演示用,实际写的时候要摘出来写成依赖属性
  227. _focusVisual.Fill = new SolidColorBrush(Color.FromArgb(0xff, 0xff, 0x0, 0x0));
  228.  
  229. _container.Children.Insert(, _focusVisual);
  230. }
  231.  
  232. private bool FocusElementsAreCreated()
  233. {
  234. return _focusVisual != null;
  235. }
  236.  
  237. private bool PointerOverElementsAreCreated()
  238. {
  239. return _pointerOverBorder != null;
  240. }
  241. }
  242. }

Controls/CollectionControl/ItemsControlDemo/MyItemPresenterDemo.xaml

  1. <Page
  2. x:Class="Windows10.Controls.CollectionControl.ItemsControlDemo.MyItemPresenterDemo"
  3. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  4. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  5. xmlns:local="using:Windows10.Controls.CollectionControl.ItemsControlDemo"
  6. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  7. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  8. mc:Ignorable="d">
  9.  
  10. <Page.Resources>
  11. <Style x:Key="MyGridViewItemPresenterTemplate" TargetType="GridViewItem">
  12. <Setter Property="Background" Value="Transparent"/>
  13. <Setter Property="Template">
  14. <Setter.Value>
  15. <ControlTemplate TargetType="GridViewItem">
  16. <!--
  17. 自定义 ContentPresenter 实现类似 GridViewItemPresenter 和 ListViewItemPresenter 的效果
  18. -->
  19. <local:MyItemPresenter />
  20. </ControlTemplate>
  21. </Setter.Value>
  22. </Setter>
  23. </Style>
  24. </Page.Resources>
  25.  
  26. <Grid Background="Transparent">
  27. <GridView x:Name="gridView" SelectionMode="Single" Margin="10 0 10 10"
  28. ItemContainerStyle="{StaticResource MyGridViewItemPresenterTemplate}">
  29. <GridView.ItemTemplate>
  30. <DataTemplate>
  31. <Grid Height="100" Width="100" Background="Blue">
  32. <TextBlock x:Name="lblName" Text="{Binding Name}" Foreground="Yellow" />
  33. </Grid>
  34. </DataTemplate>
  35. </GridView.ItemTemplate>
  36. </GridView>
  37. </Grid>
  38. </Page>

Controls/CollectionControl/ItemsControlDemo/MyItemPresenterDemo.xaml.cs

  1. /*
  2. * 本例用于演示如何自定义 ContentPresenter 实现类似 GridViewItemPresenter 和 ListViewItemPresenter 的效果
  3. */
  4.  
  5. using Windows.UI.Xaml.Controls;
  6. using Windows.UI.Xaml.Navigation;
  7. using Windows10.Common;
  8.  
  9. namespace Windows10.Controls.CollectionControl.ItemsControlDemo
  10. {
  11. public sealed partial class MyItemPresenterDemo : Page
  12. {
  13. public MyItemPresenterDemo()
  14. {
  15. this.InitializeComponent();
  16. }
  17.  
  18. protected override void OnNavigatedTo(NavigationEventArgs e)
  19. {
  20. gridView.ItemsSource = TestData.GetEmployees();
  21. }
  22. }
  23. }

OK
[源码下载]

背水一战 Windows 10 (52) - 控件(集合类): ItemsControl - 自定义 ItemsControl, 自定义 ContentPresenter的更多相关文章

  1. 背水一战 Windows 10 (50) - 控件(集合类): ItemsControl - 基础知识, 数据绑定, ItemsPresenter, GridViewItemPresenter, ListViewItemPresenter

    [源码下载] 背水一战 Windows 10 (50) - 控件(集合类): ItemsControl - 基础知识, 数据绑定, ItemsPresenter, GridViewItemPresen ...

  2. 背水一战 Windows 10 (51) - 控件(集合类): ItemsControl - 项模板选择器, 数据分组

    [源码下载] 背水一战 Windows 10 (51) - 控件(集合类): ItemsControl - 项模板选择器, 数据分组 作者:webabcd 介绍背水一战 Windows 10 之 控件 ...

  3. 背水一战 Windows 10 (53) - 控件(集合类): ItemsControl 的布局控件 - ItemsStackPanel, ItemsWrapGrid

    [源码下载] 背水一战 Windows 10 (53) - 控件(集合类): ItemsControl 的布局控件 - ItemsStackPanel, ItemsWrapGrid 作者:webabc ...

  4. 背水一战 Windows 10 (54) - 控件(集合类): ItemsControl 的布局控件 - OrientedVirtualizingPanel, VirtualizingStackPanel, WrapGrid

    [源码下载] 背水一战 Windows 10 (54) - 控件(集合类): ItemsControl 的布局控件 - OrientedVirtualizingPanel, VirtualizingS ...

  5. 背水一战 Windows 10 (49) - 控件(集合类): Pivot, Hub

    [源码下载] 背水一战 Windows 10 (49) - 控件(集合类): Pivot, Hub 作者:webabcd 介绍背水一战 Windows 10 之 控件(集合类) Pivot Hub 示 ...

  6. 背水一战 Windows 10 (48) - 控件(集合类): FlipView

    [源码下载] 背水一战 Windows 10 (48) - 控件(集合类): FlipView 作者:webabcd 介绍背水一战 Windows 10 之 控件(集合类) FlipView 示例Fl ...

  7. 背水一战 Windows 10 (55) - 控件(集合类): SemanticZoom, ISemanticZoomInformation

    [源码下载] 背水一战 Windows 10 (55) - 控件(集合类): SemanticZoom, ISemanticZoomInformation 作者:webabcd 介绍背水一战 Wind ...

  8. 背水一战 Windows 10 (56) - 控件(集合类): ListViewBase - 基础知识, 拖动项

    [源码下载] 背水一战 Windows 10 (56) - 控件(集合类): ListViewBase - 基础知识, 拖动项 作者:webabcd 介绍背水一战 Windows 10 之 控件(集合 ...

  9. 背水一战 Windows 10 (57) - 控件(集合类): ListViewBase - 增量加载, 分步绘制

    [源码下载] 背水一战 Windows 10 (57) - 控件(集合类): ListViewBase - 增量加载, 分步绘制 作者:webabcd 介绍背水一战 Windows 10 之 控件(集 ...

随机推荐

  1. 7-性能测试i报告

    性能测试报告概述 1.测试报告是指把测试的过程和结果写成文档:对发现的问题和缺陷进行分析:为纠正软件的存在的质量问题提供依据: 为软件验收和交付打下基础 2.性能测试报告属于软件测试报告的一种,主要针 ...

  2. DataTable xml 互相转换

    //测试方法 public static DataTable Test() { string savePath = System.AppDomain.CurrentDomain.BaseDirecto ...

  3. ios蓝牙自定义快捷键

    http://www.paopaoche.net/app/12072.html Beekeyboard  

  4. oracle 大量连接导致数据库不能登录

    系统遇到过几次这种问题,一个系统申请的session数过大,导致数据库进程数满,无法连接的问题. pl sql develope 报的错误是:ORA-12170:TNS:链接超时 oracle用户登录 ...

  5. Java 学习之集合类(Collections)

    Collection(集合类) 我们是使用数组来保存数据,但是他的长度一旦创建,就已经确定了,当我们要动态传入穿值,数组就有些局限了,集合类就孕育而生:所谓集合,就是来保存,盛装数据,也可称为容器类: ...

  6. 构造函数的prototype和constructor属性

    Car.prototype = { name:'BMW', height:1400, long:4900 } function Car(color,owner){ this.color = color ...

  7. visual studio的试用版评估期已结束 解决办法

    启动visual studio 2008后显示对话框:visual studio的试用版评估期已结束.下面有两个按钮,点第一个链接到微软网页,第二个直接关闭.虽然大多数高手已经知道如何解决,但对菜鸟来 ...

  8. ubuntu server 在 virtualbox中安装增强包

    原文链接:http://luzl.iteye.com/blog/1010597 首先说下增强包能干什么,在desktop下面有了增强包桌面就能变大了,在server下也是类似,那个黑屏就能变大了,还有 ...

  9. vue+大文件分片上传

    最近公司在使用vue做工程项目,实现大文件分片上传. 网上找了一天,发现网上很多代码都存在很多问题,最后终于找到了一个符合要求的项目. 工程如下: 对项目的大文件上传功能做出分析,怎么实现大文件分片上 ...

  10. nginx调优操作之nginx隐藏其版本号

    1.nginx下载 下载网址:nginx.org 2.解压nginx [root@iZwz9cl4i8oy1reej7o8pmZ soft]# ls nginx-.tar.gz [root@iZwz9 ...