WPF真入门教程27--项目案例--设备数据实时监测

这篇具有很好参考价值的文章主要介绍了WPF真入门教程27--项目案例--设备数据实时监测。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、上图看效果

今天要做的一个案例是这样的效果,它能实时监测车间设备有关数据,并以表格和图形显示在界面上,这个比上个案例要复杂些,颜值也高些,通过这个来巩固wpf的技能,用到了命令绑定,样式资源,表格数据,图形控件livechart。将前面25的内容熟悉起来,就可以自己动手做这个案例了。

WPF真入门教程27--项目案例--设备数据实时监测,WPF真入门教程,wpf,数据绑定,布局,datagrid,C#

2、创建wpf项目

WPF真入门教程27--项目案例--设备数据实时监测,WPF真入门教程,wpf,数据绑定,布局,datagrid,C#

WPF真入门教程27--项目案例--设备数据实时监测,WPF真入门教程,wpf,数据绑定,布局,datagrid,C#

WPF真入门教程27--项目案例--设备数据实时监测,WPF真入门教程,wpf,数据绑定,布局,datagrid,C#

WPF真入门教程27--项目案例--设备数据实时监测,WPF真入门教程,wpf,数据绑定,布局,datagrid,C#

 

3、 UI布局分析

整个界面是一个表格,表格分二行,第一行是标题栏,第二行是数据栏,

第二行分2列,第1列放表格控件,第2列放图形控件

WPF真入门教程27--项目案例--设备数据实时监测,WPF真入门教程,wpf,数据绑定,布局,datagrid,C#

第一行分7列,放7个控件

WPF真入门教程27--项目案例--设备数据实时监测,WPF真入门教程,wpf,数据绑定,布局,datagrid,C#

 WPF真入门教程27--项目案例--设备数据实时监测,WPF真入门教程,wpf,数据绑定,布局,datagrid,C#

1、 第一行

WPF真入门教程27--项目案例--设备数据实时监测,WPF真入门教程,wpf,数据绑定,布局,datagrid,C#

2、第二行

 WPF真入门教程27--项目案例--设备数据实时监测,WPF真入门教程,wpf,数据绑定,布局,datagrid,C#

WPF真入门教程27--项目案例--设备数据实时监测,WPF真入门教程,wpf,数据绑定,布局,datagrid,C# 

WPF中的布局是表格布局风格,通过一个个的细化组合形成UI,完整代码如下,大家可以仔细看看,注释都有,仔细体会下,不算难:

<Window x:Class="OmRonMesWPFApp.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:OmRonMesWPFApp.ViewModel"
         xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf" 
       FontSize="12" FontFamily="Microsoft YaHei" FontWeight="ExtraLight" Title="煅烧车间运行监测" Height="740" Width="1300" WindowStartupLocation="CenterScreen" Name="loginWin"   >
    <Window.DataContext>
        <local:MainViewModel/>
    </Window.DataContext>
    <Grid Background="Honeydew" ShowGridLines="true">
        <Grid.RowDefinitions>
            <RowDefinition Height="40"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <!--第一行标题-->
        <Grid Grid.Row="0" Margin="0" Background="CornflowerBlue" >
            <Grid.ColumnDefinitions>
                <ColumnDefinition  />
                <ColumnDefinition  />
                <ColumnDefinition  />
                <ColumnDefinition  />
                <ColumnDefinition  />
                <ColumnDefinition  />
                <ColumnDefinition  />
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column="0" Text="PLC地址" Style="{StaticResource  txtTextBlockStyle}" HorizontalAlignment="Center"/>
            <TextBox  Grid.Column="1"   VerticalContentAlignment="Center"  Text="{Binding HostName}" Style="{StaticResource  txtTextBoxStyle}"   />
            <TextBlock Grid.Column="2" Text="端口号" Style="{StaticResource  txtTextBlockStyle}" HorizontalAlignment="Center"/>
            <TextBox Grid.Column="3"   VerticalContentAlignment="Center"  Text="{Binding HostPort}"   Style="{StaticResource  txtTextBoxStyle}" />
            <Button Grid.Column="4" Content="连 接"  Style="{StaticResource btnBaseStyle}"     Command="{Binding LoginCommand}" CommandParameter="{Binding ElementName=loginWin}" />
            <Button Grid.Column="5" Content="断 开"   Style="{StaticResource btnBaseStyle}"  />
            <TextBlock Grid.Column="6" FontSize="19" Text="{Binding ConnectWords,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" Style="{StaticResource  txtTextBlockStyle}"   Foreground="White"/>
        </Grid>
        <!--第二行信息-->
        <Grid Grid.Row="1" Margin="0 10 0 0">
            <Grid.ColumnDefinitions>
                <!--所占百分比50%-->
                <ColumnDefinition Width="45*"  />
                <ColumnDefinition Width="55*"   />
            </Grid.ColumnDefinitions>
            <!--第1列布局:数据列表-->
            <DataGrid Name="gridCustomers" Margin="10 5 5 5"  Grid.Column="0" ItemsSource="{Binding HouseList}"  SelectedItem="{Binding CurrentItem}"   Style="{StaticResource dgStyle}">
                <DataGrid.Columns>
                    <!--绑定视图模型中的CustInfo对象各个属性-->
                    <DataGridTextColumn Binding="{Binding Id}" Header="序号"  IsReadOnly="True"  ElementStyle="{StaticResource textColStyleLeft}" Width="70" />
                    <DataGridTextColumn Binding="{Binding Name}" Header="名称"  IsReadOnly="True"  ElementStyle="{StaticResource textColStyleLeft}" Width="110" />
                    <DataGridTextColumn Binding="{Binding Temperature}" Header="温度"  IsReadOnly="True"   ElementStyle="{StaticResource textColStyleLeft}"  Width="110"/>
                    <DataGridTextColumn Binding="{Binding Waterlevel}" Header="水位"   IsReadOnly="True" ElementStyle="{StaticResource textColStyleLeft}" Width="110" />
                    <DataGridTextColumn Binding="{Binding Speed}" Header="转速"  IsReadOnly="True"  ElementStyle="{StaticResource textColStyleLeft}"  Width="110"/>
                    <DataGridTextColumn Binding="{Binding Corner}" Header="转角"  IsReadOnly="True"  ElementStyle="{StaticResource textColStyleLeft}"  Width="110" />
                    <DataGridTextColumn Binding="{Binding Inserttime,StringFormat='yyyy年MM月dd日HH时mm分'}" Header="创建时间"  IsReadOnly="True"  ElementStyle="{StaticResource textColStyleLeft}" Width="*" />
                </DataGrid.Columns>
            </DataGrid>
            <!--第2列布局:图形列表-->
            <Grid Grid.Column="1" >
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="641*"/>
                    <ColumnDefinition Width="74*"/>
                </Grid.ColumnDefinitions>
                <!--柱状图-->
                <!--LegendLocation图例位置,Series序列绑定vm中的HouseSeriesList属性 -->
                <lvc:CartesianChart Series="{Binding HouseSeriesList}" LegendLocation="Top" Margin="10,10,10,10" Grid.ColumnSpan="2">
                    <!--X坐标-->
                    <lvc:CartesianChart.AxisX>
                        <lvc:Axis Labels="{Binding Labels}" FontSize="14" Position="LeftBottom" Foreground="Black" >
                            <!--分隔线-->
                            <lvc:Axis.Separator>
                                <lvc:Separator Stroke="LightBlue" StrokeThickness="2"/>
                            </lvc:Axis.Separator>
                        </lvc:Axis>
                    </lvc:CartesianChart.AxisX>
                    <!--Y坐标-->
                    <lvc:CartesianChart.AxisY>
                        <lvc:Axis Title="最新运行数据"  FontSize="14" Position="LeftBottom" Foreground="DarkSlateBlue" ShowLabels="True">
                            <lvc:Axis.Separator>
                                <lvc:Separator Step="4" Stroke="LightBlue" StrokeThickness="1"/>
                            </lvc:Axis.Separator>
                        </lvc:Axis>
                    </lvc:CartesianChart.AxisY>
                </lvc:CartesianChart>
            </Grid>
        </Grid>
    </Grid>
</Window>

3、样式资源

WPF真入门教程27--项目案例--设备数据实时监测,WPF真入门教程,wpf,数据绑定,布局,datagrid,C#

样式文件就是WEB中的css属性设置,需要精细的考虑,软件的界面就是一个人的颜值,可以看看,用的时候改改。

 

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <!--定义通用的按钮样式-->
    <Style TargetType="{x:Type Button}" x:Key="btnBaseStyle">
        <Setter Property="Height" Value="30"/>
        <Setter Property="Width" Value="90"/>
        <Setter Property="FontFamily" Value="微软雅黑"/>
        <Setter Property="Margin" Value="3,0"/>
        <Setter Property="FontSize" Value="16"/>
        <Setter Property="FontWeight" Value="Bold"/>
        <Setter Property="Foreground"  Value="Blue"/>
        <!--模板的样式-->
        <Setter Property="Template">
            <Setter.Value>
                <!--Button按钮样式-->
                <ControlTemplate TargetType="Button">
                    <Grid >
                        <Border Background="{TemplateBinding Background}" CornerRadius="13" >
                            <TextBlock Margin="10 5 10 5" Text="{TemplateBinding Content}" FontSize="{TemplateBinding FontSize}" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
                        </Border>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <!--鼠标放上去时的触发器-->
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Background" Value="White" ></Setter>
                        </Trigger>
                    </ControlTemplate.Triggers>

                </ControlTemplate>
            </Setter.Value>
        </Setter> 
    </Style>

    <!--TextBox默认样式-->
    <Style TargetType="{x:Type TextBox}" x:Key="txtTextBoxStyle">
        <Setter Property="Width" Value="150"/>
        <Setter Property="Height" Value="20"/>
        <Setter Property="BorderBrush" Value="#FF105190"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="Margin" Value="2,0"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>
        <Setter Property="Background">
            <Setter.Value>
                <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
                    <GradientStop Color="White" Offset="0"/>
                    <GradientStop Color="#FFE4E4E4" Offset="1"/>
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
    </Style>

    <!--TextBlock默认样式-->
    <Style TargetType="{x:Type TextBlock}" x:Key="txtTextBlockStyle">
        <Setter Property="Margin" Value="1"/>
        <Setter Property="Height" Value="24"/>
        <Setter Property="Foreground" Value="White"/>
        <Setter Property="FontSize" Value="20"></Setter>
    </Style>

    <!--页面下拉框样式-->
    <LinearGradientBrush x:Key="ComboBox.Static.Background" EndPoint="0,1" StartPoint="0,0">
        <GradientStop Color="White" Offset="0"/>
        <GradientStop Color="#FFE4E4E4" Offset="1"/>
    </LinearGradientBrush>
    <SolidColorBrush x:Key="ComboBox.Static.Border" Color="#FF105190"/>

    <!--combox默认样式-->
    <Style x:Key="cboStyle" TargetType="{x:Type ComboBox}">
        <Setter Property="Background" Value="{StaticResource ComboBox.Static.Background}"/>
        <Setter Property="BorderBrush" Value="{StaticResource ComboBox.Static.Border}"/>
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
        <Setter Property="Width" Value="150"/>
        <Setter Property="Height" Value="25"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
        <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
        <Setter Property="Padding" Value="6,3,5,3"/>
        <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
        <Setter Property="ScrollViewer.PanningMode" Value="Both"/>
        <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
    </Style>
</ResourceDictionary>

WPF真入门教程27--项目案例--设备数据实时监测,WPF真入门教程,wpf,数据绑定,布局,datagrid,C#

 

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <!--所有datagrid控件页面的样式-->
    <Style TargetType="TextBlock" x:Key="textColStyleCenter">
        <Setter Property="VerticalAlignment" Value="Center"/>
        <Setter Property="TextAlignment" Value="Center"/>
    </Style>
    <Style TargetType="TextBlock" x:Key="textColStyleLeft">
        <Setter Property="VerticalAlignment" Value="Center"/>
        <Setter Property="TextAlignment" Value="Left"/>
        <Setter Property="Padding" Value="5,0"/>
    </Style>
    <Style TargetType="CheckBox" x:Key="chkColStyle">
        <Setter Property="VerticalAlignment" Value="Center"/>
        <Setter Property="HorizontalAlignment" Value="Center"/>
    </Style>
    
    <!--dg表格行的样式-->
    <Style TargetType="{x:Type DataGridRow}" x:Key="dgRowStyle">
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>
        <Style.Triggers>
            <Trigger Property="ItemsControl.AlternationIndex" Value="0">
                <Setter Property="Background" Value="#FFD5EFF7"/>
            </Trigger>
            <Trigger Property="ItemsControl.AlternationIndex" Value="1">
                <Setter Property="Background" Value="#FFFBFCF9"/>
            </Trigger>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Background">
                    <Setter.Value>
                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                            <GradientStop Color="#FF73BCE8" Offset="0.98"/>
                            <GradientStop Color="White" Offset="0"/>
                        </LinearGradientBrush>
                    </Setter.Value>
                </Setter>
            </Trigger>
            <Trigger Property="IsSelected" Value="True">
                <Setter Property="Background">
                    <Setter.Value>
                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                            <GradientStop Color="#FF5C8DE0" Offset="0.98"/>
                            <GradientStop Color="White" Offset="0"/>
                        </LinearGradientBrush>
                    </Setter.Value>
                </Setter>
            </Trigger>
        </Style.Triggers>
    </Style>
    
    <!--dg表格列的样式-->
    <Style x:Key="colStyle"  TargetType="DataGridColumnHeader">
        <Setter Property="FontWeight" Value="Bold"/>
        <Setter Property="Foreground" Value="#FF7C6BE0"/>
    </Style>
     
    
    <!--dg表格样式-->
    <Style TargetType="DataGrid" x:Key="dgStyle">
        <Setter Property="HorizontalAlignment" Value="Stretch"/>
        <Setter Property="AutoGenerateColumns" Value="False"/>
        <Setter Property="SelectionMode" Value="Extended"/>
        <Setter Property="VerticalAlignment" Value="Stretch"/>
        <Setter Property="CanUserAddRows" Value="False"/>
        <Setter Property="RowHeaderWidth" Value="20"/>
        <Setter Property="HeadersVisibility" Value="Column"/>
        <!--隔行显示-->
        <Setter Property="AlternationCount" Value="2"/>
        <Setter Property="HorizontalScrollBarVisibility" Value="Auto"/>
        <Setter Property="VerticalScrollBarVisibility" Value="Auto"/>
        <Setter Property="SelectionUnit" Value="FullRow"/>
        <Setter Property="ColumnHeaderHeight" Value="25"/>
        <Setter Property="RowHeight" Value="25"/>
        <Setter Property="HorizontalGridLinesBrush" Value="LightGray"/>
        <Setter Property="VerticalGridLinesBrush" Value="LightGray"/>
        <Setter Property="ColumnHeaderStyle" Value="{StaticResource colStyle}"/>
        <Setter Property="Margin" Value="5,20,0,5"/>
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="BorderBrush" Value="LightGray"/>
        <Setter Property="RowStyle" Value="{StaticResource dgRowStyle}"/>
    </Style>

</ResourceDictionary>

4、视图模型

视图模型的意思是指UI界面与后台的哪个模型类绑定起来,业务逻辑由视图模型来决定,前台的UI界面只负责数据的渲染,这里都是命令绑定和属性绑定。

WPF真入门教程27--项目案例--设备数据实时监测,WPF真入门教程,wpf,数据绑定,布局,datagrid,C#

 

WPF真入门教程27--项目案例--设备数据实时监测,WPF真入门教程,wpf,数据绑定,布局,datagrid,C#

 1、命令绑定

2、属性绑定

 WPF真入门教程27--项目案例--设备数据实时监测,WPF真入门教程,wpf,数据绑定,布局,datagrid,C#

这里是图形的参数绑定后台属性,意思是一样的。注意什么时候用双向,单向。当后台逻辑数据发生更改时,需要更新UI控件就使用双向绑定。

WPF真入门教程27--项目案例--设备数据实时监测,WPF真入门教程,wpf,数据绑定,布局,datagrid,C#

可以看下这些

WPF真入门教程19--对象数据绑定_wpf 查询绑定对象-CSDN博客

WPF真入门教程18--XML数据绑定_wpf xml-CSDN博客

WPF真入门教程17--双向数据绑定_wpf 双向绑定-CSDN博客

WPF真入门教程16--简单数据绑定_wpf中的textblock怎么绑定变量-CSDN博客

WPF真入门教程15--什么是数据绑定?_数据插入的时候提示绑定数值是什么-CSDN博客

5、运行起来

 这里面用到异步task,而不是winform中的定时器。WPF真入门教程27--项目案例--设备数据实时监测,WPF真入门教程,wpf,数据绑定,布局,datagrid,C#

 希望帮到你,就是我最大的支柱,动动您的金手指,创作不易,整理不易,多多给矛点击支持,发财的小手指动起来。

WPF真入门教程27--项目案例--设备数据实时监测,WPF真入门教程,wpf,数据绑定,布局,datagrid,C#文章来源地址https://www.toymoban.com/news/detail-790966.html

到了这里,关于WPF真入门教程27--项目案例--设备数据实时监测的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • WPF真入门教程02--新建WPF工程

    在VS开发环境安装完成之后,首先我们先新建一个WPF工程,然后对工程目录结构啥的要有所了解才行。 打开VS2019      工程建好之后,WPF应用程序”会在“引用”里面自动添加下图中所示的 PresentationCore、PresentationFramework、WindowsBase三大核心程序集,就是下面这个样子   默认

    2024年02月03日
    浏览(67)
  • Gradio入门到进阶全网最详细教程[一]:快速搭建AI算法可视化部署演示(侧重项目搭建和案例分享)

    常用的两款AI可视化交互应用比较: Gradio Gradio的优势在于易用性,代码结构相比Streamlit简单,只需简单定义输入和输出接口即可快速构建简单的交互页面,更轻松部署模型。适合场景相对简单,想要快速部署应用的开发者。便于分享:gradio可以在启动应用时设置share=True参数

    2023年04月25日
    浏览(46)
  • WPF入门教程系列一——基础

    一、 前言            最近在学习WPF,学习WPF首先上的是微软的MSDN,然后再搜索了一下网络有关WPF的学习资料。为了温故而知新把学习过程记录下来,以备后查。这篇主要讲WPF的开发基础,介绍了如何使用Visual Studio 2013创建一个WPF应用程序。 首先说一下学习WPF的基础知

    2024年02月07日
    浏览(52)
  • WPF 入门教程DockPanel介绍

    在 DockPanel中 可以很容易地停靠在所有四个方向的内容(上,下,左,右)。这使它在许多情况下成为一个很好的选择,您希望将窗口划分为特定区域,特别是因为默认情况下,DockPanel 内的最后一个元素,除非此功能被明确禁用,否则将自动填充其余空间(中心)。 我们在

    2024年02月05日
    浏览(46)
  • WPF教程_编程入门自学教程_菜鸟教程-免费教程分享

    WPF教程 WPF - 概述 WPF - 环境设置 WPF - Hello World WPF - XAML概述 WPF - Elements Tree WPF - 依赖属性 WPF - 路由事件 WPF - 控件 WPF - 布局 WPF - 布局嵌套 WPF - 输入 WPF - 命令行 WPF - 数据绑定 WPF - 资源 WPF - 模板 WPF - 样式 WPF - 触发器 WPF - 调试 WPF - 自定义控件 WPF - 异常处理 WPF - 本地化 WPF - 互

    2023年04月27日
    浏览(54)
  • WPF 入门教程Grid使用技巧

    在上一章中,我们向您介绍了出色的 Grid 面板,并向您展示了一些有关如何使用它的基本示例。在本章中,我们将进行一些更高级的布局,因为这是 Grid 真正闪耀的地方。首先,让我们加入更多的列甚至一些行,以获得真正的表格布局: 总共九个按钮,每个按钮都放置在自己

    2024年02月06日
    浏览(47)
  • WPF真入门教程12--ListView控件

           ListView 控件在Windows应用程序中常用,用于表示数据列表。如果您以前使用过 WinForms,那么您对ListView的实用性有一个很好的了解,但您应该意识到 WPF中的ListView 不像WinForms版本那样使用。再一次的主要区别在于,虽然WinForms ListView只是调用Windows API 函数来呈现常见的

    2024年02月04日
    浏览(54)
  • WPF 入门教程DispatcherTimer计时器

    https://www.zhihu.com/tardis/bd/art/430630047?source_id=1001 在 WinForms 中,有一个名为 Timer 的控件,它可以在给定的时间间隔内重复执行一个操作。WPF 也有这种可能性,但我们有 DispatcherTimer 控件,而不是不可见的控件。它几乎做同样的事情,但不是将它放在表单上,​​而是专门从代码

    2024年01月22日
    浏览(49)
  • 第27章_瑞萨MCU零基础入门系列教程之freeRTOS实验

    本教程基于韦东山百问网出的 DShanMCU-RA6M5开发板 进行编写,需要的同学可以在这里获取: https://item.taobao.com/item.htm?id=728461040949 配套资料获取:https://renesas-docs.100ask.net 瑞萨MCU零基础入门系列教程汇总 : https://blog.csdn.net/qq_35181236/article/details/132779862 本章目标 学会使用RASC创建

    2024年02月09日
    浏览(40)
  • WPF真入门教程23--MVVM简单介绍

            在WPF开发中,经典的编程模式是MVVM,是为WPF量身定做的模式,该模式充分利用了WPF的数据绑定机制,最大限度地降低了Xmal文件和CS文件的耦合度,也就是UI显示和逻辑代码的耦合度,如需要更换界面时,逻辑代码修改很少,甚至不用修改。与WinForm开发相比,我们一般

    2024年02月03日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包