5. Prism系列之区域管理器

news2024/9/20 14:31:01

Prism系列之区域管理器


文章目录

  • Prism系列之区域管理器
    • 一、区域管理器
    • 二、区域创建与视图的注入
      • 1. ViewDiscovery
      • 2. ViewInjection
    • 三、激活与失效视图
      • 1. Activate和Deactivate
      • 2. 监控视图激活状态
      • 3. Add和Remove
    • 四、自定义区域适配器
      • 1. 创建自定义适配器
      • 2. 注册映射
      • 3. 创建区域


一、区域管理器

这篇文章将会讲解之前项目中用到的利用区域管理器更好的对我们的View进行管理,同样的我们来看看官方给出的模型图:

在这里插入图片描述

大致一个区域管理器RegionMannager对一个控件创建区域的要点:

  1. 创建Region的控件必须包含一个RegionAdapter适配器
  2. Region是依赖在具有RegionAdapter控件身上的

其实后来我去看了下官方的介绍和源码,默认RegionAdapter是有三个,且还支持自定义RegionAdapter,因此在官方的模型图之间我做了点补充:

在这里插入图片描述

二、区域创建与视图的注入

我们先来看看我们之前项目的区域的划分,以及如何创建区域并且把View注入到区域中:

在这里插入图片描述

把整个主窗体划分了四个区域:

  • ShowSearchPatientRegion:注入了ShowSearchPatient视图
  • PatientListRegion:注入了PatientList视图
  • FlyoutRegion:注入了PatientDetailSearchMedicine视图
  • ShowSearchPatientRegion:注入了ShowSearchPatient视图

Prism中,我们有两种方式去实现区域创建和视图注入:

  1. ViewDiscovery
  2. ViewInjection

1. ViewDiscovery

我们截取其中PatientListRegion的创建和视图注入的代码

MainWindow.xaml:

<ContentControl Grid.Row="2" prism:RegionManager.RegionName="PatientListRegion" Margin="10"/>

这里相当于在后台MainWindow.cs:

RegionManager.SetRegionName(ContentControl, "PatientListRegion");

PatientModule.cs:

 public class PatientModule : IModule
 {
    public void OnInitialized(IContainerProvider containerProvider)
    {
         var regionManager = containerProvider.Resolve<IRegionManager>();
         //PatientList
         regionManager.RegisterViewWithRegion(RegionNames.PatientListRegion, typeof(PatientList));
         //PatientDetail-Flyout
         regionManager.RegisterViewWithRegion(RegionNames.FlyoutRegion, typeof(PatientDetail));
           
     }

    public void RegisterTypes(IContainerRegistry containerRegistry)
    {
           
    }
 }

2. ViewInjection

我们在MainWindow窗体的Loaded事件中使用ViewInjection方式注入视图PatientList

MainWindow.xaml:

  <i:Interaction.Triggers>
      <i:EventTrigger EventName="Loaded">
          <i:InvokeCommandAction Command="{Binding LoadingCommand}"/>
       /i:EventTrigger>
  </i:Interaction.Triggers>

MainWindowViewModel.cs:

private IRegionManager _regionManager;
private IRegion _paientListRegion;        
private PatientList _patientListView;

private DelegateCommand _loadingCommand;
public DelegateCommand LoadingCommand =>
     _loadingCommand ?? (_loadingCommand = new DelegateCommand(ExecuteLoadingCommand));

void ExecuteLoadingCommand()
{
     _regionManager = CommonServiceLocator.ServiceLocator.Current.GetInstance<IRegionManager>();
     _paientListRegion = _regionManager.Regions[RegionNames.PatientListRegion];
     _patientListView = CommonServiceLocator.ServiceLocator.Current.GetInstance<PatientList>();
     _paientListRegion.Add(_patientListView);

 }

我们可以明显的感觉到两种方式的不同,ViewDiscovery方式是自动地实例化视图并且加载出来,而ViewInjection方式则是可以手动控制注入视图和加载视图的时机(上述例子是通过Loaded事件),官方对于两者的推荐使用场景如下:

ViewDiscovery:

  • 需要或要求自动加载视图
  • 视图的单个实例将加载到该区域中

ViewInjection:

  • 需要显式或编程控制何时创建和显示视图,或者您需要从区域中删除视图
  • 需要在区域中显示相同视图的多个实例,其中每个视图实例都绑定到不同的数据
  • 需要控制添加视图的区域的哪个实例
  • 应用程序使用导航API

三、激活与失效视图

1. Activate和Deactivate

首先我们需要控制PatientListMedicineMainContent两个视图的激活情况,上代码:

MainWindow.xaml:

<StackPanel Grid.Row="1">
    <Button  Content="Load MedicineModule" FontSize="25"  Margin="5" Command="{Binding LoadMedicineModuleCommand}"/>
     <UniformGrid Margin="5">
         <Button Content="ActivePaientList" Margin="5" Command="{Binding ActivePaientListCommand}"/>
         <Button Content="DeactivePaientList" Margin="5" Command="{Binding DeactivePaientListCommand}"/>
         <Button Content="ActiveMedicineList" Margin="5" Command="{Binding ActiveMedicineListCommand}"/>
         <Button Content="DeactiveMedicineList" Margin="5" Command="{Binding DeactiveMedicineListCommand}"/>
     </UniformGrid>
</StackPanel>

<ContentControl Grid.Row="2" prism:RegionManager.RegionName="PatientListRegion" Margin="10"/>
<ContentControl Grid.Row="3" prism:RegionManager.RegionName="MedicineMainContentRegion"/>

MainWindowViewModel.cs:

  private IRegionManager _regionManager;
  private IRegion _paientListRegion;
  private IRegion _medicineListRegion;
  private PatientList _patientListView;
  private MedicineMainContent _medicineMainContentView;

  private bool _isCanExcute = false;
  public bool IsCanExcute
  {
     get { return _isCanExcute; }
     set { SetProperty(ref _isCanExcute, value); }
  }

  private DelegateCommand _loadingCommand;
  public DelegateCommand LoadingCommand =>
      _loadingCommand ?? (_loadingCommand = new DelegateCommand(ExecuteLoadingCommand));

  private DelegateCommand _activePaientListCommand;
  public DelegateCommand ActivePaientListCommand =>
      _activePaientListCommand ?? (_activePaientListCommand = new DelegateCommand(ExecuteActivePaientListCommand));

  private DelegateCommand _deactivePaientListCommand;
  public DelegateCommand DeactivePaientListCommand =>
      _deactivePaientListCommand ?? (_deactivePaientListCommand = new DelegateCommand(ExecuteDeactivePaientListCommand));

   private DelegateCommand _activeMedicineListCommand;
   public DelegateCommand ActiveMedicineListCommand =>
      _activeMedicineListCommand ?? (_activeMedicineListCommand = new DelegateCommand(ExecuteActiveMedicineListCommand)
      .ObservesCanExecute(() => IsCanExcute));

   private DelegateCommand _deactiveMedicineListCommand;
   public DelegateCommand DeactiveMedicineListCommand =>
       _deactiveMedicineListCommand ?? (_deactiveMedicineListCommand = new DelegateCommand(ExecuteDeactiveMedicineListCommand)
      .ObservesCanExecute(() => IsCanExcute));

   private DelegateCommand _loadMedicineModuleCommand;
   public DelegateCommand LoadMedicineModuleCommand =>
       _loadMedicineModuleCommand ?? (_loadMedicineModuleCommand = new DelegateCommand(ExecuteLoadMedicineModuleCommand));

 /// <summary>
 /// 窗体加载事件
 /// </summary>
 void ExecuteLoadingCommand()
 {
      _regionManager = CommonServiceLocator.ServiceLocator.Current.GetInstance<IRegionManager>();
      _paientListRegion = _regionManager.Regions[RegionNames.PatientListRegion];
      _patientListView = CommonServiceLocator.ServiceLocator.Current.GetInstance<PatientList>();
      _paientListRegion.Add(_patientListView);
      _medicineListRegion = _regionManager.Regions[RegionNames.MedicineMainContentRegion];
 }

  /// <summary>
  /// 失效medicineMainContent视图
  /// </summary>
  void ExecuteDeactiveMedicineListCommand()
  {
      _medicineListRegion.Deactivate(_medicineMainContentView);
  }

  /// <summary>
  /// 激活medicineMainContent视图
  /// </summary>
  void ExecuteActiveMedicineListCommand()
  {
      _medicineListRegion.Activate(_medicineMainContentView);
  }

  /// <summary>
  /// 失效patientList视图
  /// </summary>
  void ExecuteDeactivePaientListCommand()
  {
       _paientListRegion.Deactivate(_patientListView);
  }

  /// <summary>
  /// 激活patientList视图
  /// </summary>
  void ExecuteActivePaientListCommand()
  {
       _paientListRegion.Activate(_patientListView);
  }
  
  /// <summary>
  /// 加载MedicineModule
  /// </summary>
  void ExecuteLoadMedicineModuleCommand()
  {
       _moduleManager.LoadModule("MedicineModule");
       _medicineMainContentView = (MedicineMainContent)_medicineListRegion.Views
            .Where(t => t.GetType() == typeof(MedicineMainContent)).FirstOrDefault();
       this.IsCanExcute = true;
   }

2. 监控视图激活状态

Prism其中还支持监控视图的激活状态,是通过在View中继承IActiveAware来实现的,我们以监控其中MedicineMainContent视图的激活状态为例子:

MedicineMainContentViewModel.cs:

 public class MedicineMainContentViewModel : BindableBase,IActiveAware
 {
     public event EventHandler IsActiveChanged;

     bool _isActive;
     public bool IsActive
     {
         get { return _isActive; }
         set
         {
             _isActive = value;
             if (_isActive)
             {
                 MessageBox.Show("视图被激活了");
             }
             else
             {
                 MessageBox.Show("视图失效了");
             }
             IsActiveChanged?.Invoke(this, new EventArgs());
          }
      }
  }

3. Add和Remove

上述例子用的是ContentControl,我们再用一个ItemsControl的例子,代码如下:

MainWindow.xaml:

  <metro:MetroWindow.RightWindowCommands>
      <metro:WindowCommands x:Name="rightWindowCommandsRegion" />
  </metro:MetroWindow.RightWindowCommands>

MainWindow.cs:

 public MainWindow()
 {
    InitializeComponent();
    var regionManager= ServiceLocator.Current.GetInstance<IRegionManager>();
    if (regionManager != null)
    {
       SetRegionManager(regionManager, this.flyoutsControlRegion, RegionNames.FlyoutRegion);
       //创建WindowCommands控件区域
       SetRegionManager(regionManager, this.rightWindowCommandsRegion, RegionNames.ShowSearchPatientRegion);
    }
 }

 void SetRegionManager(IRegionManager regionManager, DependencyObject regionTarget, string regionName)
 {
     RegionManager.SetRegionName(regionTarget, regionName);
     RegionManager.SetRegionManager(regionTarget, regionManager);
 }

ShowSearchPatient.xaml:

<StackPanel x:Class="PrismMetroSample.MedicineModule.Views.ShowSearchPatient"
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       xmlns:prism="http://prismlibrary.com/"  
       xmlns:const="clr-namespace:PrismMetroSample.Infrastructure.Constants;assembly=PrismMetroSample.Infrastructure"
       Orientation="Horizontal"    
       xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
       prism:ViewModelLocator.AutoWireViewModel="True">
   <i:Interaction.Triggers>
       <i:EventTrigger EventName="Loaded">
           <i:InvokeCommandAction Command="{Binding ShowSearchLoadingCommand}"/>
       </i:EventTrigger>
   </i:Interaction.Triggers>
   <CheckBox IsChecked="{Binding IsShow}"/>
   <Button Command="{Binding ApplicationCommands.ShowCommand}" CommandParameter="{x:Static const:FlyoutNames.SearchMedicineFlyout}">
       <StackPanel Orientation="Horizontal">
           <Image Height="20" Source="pack://application:,,,/PrismMetroSample.Infrastructure;Component/Assets/Photos/按钮.png"/>
           <TextBlock Text="Show" FontWeight="Bold" FontSize="15" VerticalAlignment="Center"/>
       </StackPanel>
   </Button>
</StackPanel>

ShowSearchPatientViewModel.cs:

 private IApplicationCommands _applicationCommands;
 private readonly IRegionManager _regionManager;
 private ShowSearchPatient _showSearchPatientView;
 private IRegion _region;

 public IApplicationCommands ApplicationCommands
 {
      get { return _applicationCommands; }
      set { SetProperty(ref _applicationCommands, value); }
 }

 private bool _isShow=true;
 public bool IsShow
 {
      get { return _isShow=true; }
      set 
      { 
          SetProperty(ref _isShow, value);
          if (_isShow)
          {
               ActiveShowSearchPatient();
          }
          else
          {
               DeactiveShowSearchPaitent();
          }
      }
 }

 private DelegateCommand _showSearchLoadingCommand;
 public DelegateCommand ShowSearchLoadingCommand =>
         _showSearchLoadingCommand ?? (_showSearchLoadingCommand = new DelegateCommand(ExecuteShowSearchLoadingCommand));

 void ExecuteShowSearchLoadingCommand()
 {
        _region = _regionManager.Regions[RegionNames.ShowSearchPatientRegion];
        _showSearchPatientView = (ShowSearchPatient)_region.Views
            .Where(t => t.GetType() == typeof(ShowSearchPatient)).FirstOrDefault();
 }


  public ShowSearchPatientViewModel(IApplicationCommands applicationCommands,IRegionManager regionManager)
  {
        this.ApplicationCommands = applicationCommands;
        _regionManager = regionManager;
  }

  /// <summary>
  /// 激活视图
  /// </summary>
  private void ActiveShowSearchPatient()
  {
       if (!_region.ActiveViews.Contains(_showSearchPatientView))
       {
           _region.Add(_showSearchPatientView);
       }         
  }
   
  /// <summary>
  /// 失效视图
  /// </summary>
   private async void DeactiveShowSearchPaitent()
   {
        _region.Remove(_showSearchPatientView);
        await Task.Delay(2000);
        IsShow = true;
   }

这里的WindowCommands 的继承链为:WindowCommands <-- ToolBar <-- HeaderedItemsControl <–ItemsControl,因此由于Prism默认的适配器有ItemsControlRegionAdapter,因此其子类也继承了其行为。

这里重点归纳一下:

  • 当进行模块化时,加载完模块才会去注入视图到区域(可参考MedicineModule视图加载顺序)
  • ContentControl控件由于Content只能显示一个,在其区域中可以通过Activate和Deactivate方法来控制显示哪个视图,其行为是由ContentControlRegionAdapter适配器控制
  • ItemsControl控件及其子控件由于显示一个集合视图,默认全部集合视图是激活的,这时候不能通过Activate和Deactivate方式来控制(会报错),通过Add和Remove来控制要显示哪些视图,其行为是由ItemsControlRegionAdapter适配器控制
  • 这里没讲到Selector控件,因为也是继承自ItemsControl,因此其SelectorRegionAdapter适配器和ItemsControlRegionAdapter适配器异曲同工
  • 可以通过继承IActiveAware接口来监控视图激活状态

四、自定义区域适配器

Prism有三个默认的区域适配器:ItemsControlRegionAdapter,ContentControlRegionAdapter,SelectorRegionAdapter,且支持自定义区域适配器,现在我们来自定义一下适配器。

1. 创建自定义适配器

UniformGridRegionAdapter.cs:

public class UniformGridRegionAdapter : RegionAdapterBase<UniformGrid>
{
    public UniformGridRegionAdapter(IRegionBehaviorFactory regionBehaviorFactory) : base(regionBehaviorFactory)
    {

    }

    protected override void Adapt(IRegion region, UniformGrid regionTarget)
    {
        region.Views.CollectionChanged += (s, e) =>
        {
          if (e.Action==System.Collections.Specialized.NotifyCollectionChangedAction.Add)
          {
              foreach (FrameworkElement element in e.NewItems)
              {
                   regionTarget.Children.Add(element);
              }
          }
        };
    }

    protected override IRegion CreateRegion()
    {
        return new AllActiveRegion();
    }
 }

2. 注册映射

App.cs:

protected override void ConfigureRegionAdapterMappings(RegionAdapterMappings regionAdapterMappings)
{
    base.ConfigureRegionAdapterMappings(regionAdapterMappings);
    //为UniformGrid控件注册适配器映射
    regionAdapterMappings.RegisterMapping(typeof(UniformGrid),Container.Resolve<UniformGridRegionAdapter>());
}

3. 创建区域

MainWindow.xaml:

<UniformGrid Margin="5" prism:RegionManager.RegionName="UniformContentRegion" Columns="2">
   <Button Content="ActivePaientList" Margin="5" Command="{Binding ActivePaientListCommand}"/>
   <Button Content="DeactivePaientList" Margin="5" Command="{Binding DeactivePaientListCommand}"/>
   <Button Content="ActiveMedicineList" Margin="5" Command="{Binding ActiveMedicineListCommand}"/>
   <Button Content="DeactiveMedicineList" Margin="5" Command="{Binding DeactiveMedicineListCommand}"/>
</UniformGrid>

我们可以看到我们为UniformGrid创建区域适配器,并且注册后,也能够为UniformGrid控件创建区域,并且注入视图显示,如果没有该区域适配器,则是会报错。

回到顶部


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Postgresql中PL/pgSQL代码块的语法与使用-声明与赋值、IF语句、CASE语句、循环语句

场景 PostGresSQL简介与Windows上的安装教程&#xff1a; PostGresSQL简介与Windows上的安装教程_postgressql windows安装免费吗?-CSDN博客 除了标准 SQL 语句之外&#xff0c;PostgreSQL 还支持使用各种过程语言&#xff08;例如 PL/pgSQL、C、PL/Tcl、PL/Python、PL/Per…

fiddler的下载、安装

在官网下载fiddler 点击Download For Windows 下载完成 安装fiddler 点击.exe文件&#xff0c;进行傻瓜式安装&#xff0c;即可安装成功 配置fiddler 点击OK后&#xff0c;重启fiddler, 即可抓包

Next.js 学习笔记(三)——路由

路由 路由基础知识 每个应用程序的骨架都是路由。本页将向你介绍互联网路由的基本概念以及如何在 Next.js 中处理路由。 术语 首先&#xff0c;你将在整个文档中看到这些术语的使用情况。以下是一个快速参考&#xff1a; 树&#xff08;Tree&#xff09;&#xff1a;用于可…

XXE利用的工作原理,利用方法及防御的案例讲解

XXE&#xff08;XML外部实体注入&#xff09;利用是一种网络安全攻击手段&#xff0c;其中攻击者利用XML解析器处理外部实体的方式中的漏洞。这种攻击主要针对的是那些使用XML来处理数据的应用程序&#xff0c;尤其是当这些应用程序没有正确限制外部实体的处理时。通过XXE利用&…

2018年第七届数学建模国际赛小美赛D题速度扼杀爱情解题全过程文档及程序

2018年第七届数学建模国际赛小美赛 D题 速度扼杀爱情 原题再现&#xff1a; 在网上约会的时代&#xff0c;有比鱼更多的浪漫选择&#xff0c;好吧&#xff0c;你知道的。例如&#xff0c;在命名恰当的网站Plenty of Fish上&#xff0c;你可以仔细查看数百或数千名潜在伴侣的档…

云原生之深入解析强大的镜像构建工具Earthly

一、Earthly 简介 Earthly 是一个更加高级的 Docker 镜像构建工具&#xff0c;Earthly 通过自己定义的 Earthfile 来代替传统的 Dockerfile 完成镜像构建&#xff1b;Earthfile 就如同 Earthly 官方所描述: Makefile Dockerfile Earthfile在使用 Earthly 进行构建镜像时目前…

护肤品类小红书素人达人的推广报价是多少?

小红书是一款集社交和电商于一体的平台&#xff0c;用户可以在上面分享生活点滴、购物心得、旅游攻略等。近年来&#xff0c;随着护肤美妆市场的不断扩大&#xff0c;越来越多的品牌和商家选择在小红书上投放广告&#xff0c;借助素人达人的影响力为产品引流。那么&#xff0c;…

Java第十七章总结

数据库基础 SQL语言 1、select 语句 select 语句用于从数据中检索数据。语法如下&#xff1a; SELECT 搜选字段列表 FROM 数据表名 WHERE 条件表达式 GROUP BY 字段名 HAVING 条件表达式(指定分组的条件) ORDER BY 字段名[ASC|DESC] 2、insert 语句 insert 语句用于向表中插入…

2024年G2电站锅炉司炉证考试题库及G2电站锅炉司炉试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年G2电站锅炉司炉证考试题库及G2电站锅炉司炉试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#xff09;特种设备作业人员上岗证考试大纲…

Spring学习?这一篇文章就够,史上最全!

文章目录 前言一、IOC概述及底层原理1.概述和原理 二、思路分析三、IOC操作bean管理&#xff08;基于xml&#xff0c;使用的是IDEA2022.3.3&#xff0c;maven仓库&#xff09;1.xml实现bean管理&#xff08;1&#xff09;创建对象&#xff08;2&#xff09;注入属性&#xff08…

SQL Server 查询处理过程

查询处理--由 SQL Server 中的关系引擎执行&#xff0c;它获取编写的 T-SQL 语句并将其转换为可以向存储引擎发出请求并检索所需结果的过程。 SQL Server 需要四个步骤来处理查询&#xff1a;分析、代化、优化和执行。 前三个步骤都由关系引擎执行&#xff1b;第三步输出的是…

一文解释JS如何获取当前系统电量

在前端浏览器中我们可以通过使用JavaScript的navigator.getBattery()方法来获取当前系统的电池情况。 这个API可以监测设备的电池状态&#xff0c;包括是否在充电、当前电量以及放电或充电所需的时间。本文将介绍如何使用这个API以及它在实际应用中的使用。 API使用 首先让我…

SD-WAN组网:企业网络的首选

在互联网技术不断更新、发展的背景之下&#xff0c;企业在面对日益复杂的网络组网需求时迫切需要一种创新的解决方案。传统的MPLS-VPN组网方式由于其高成本的特点令企业难以破局&#xff0c; SD-WAN正逐渐代替它们&#xff0c;成为企业网络组网的首选。 本文将深入探讨SD-WAN技…

广州华锐互动VRAR:利用VR开展新能源汽车触电安全演练,降低培训成本和风险

随着新能源汽车行业的快速发展&#xff0c;相关的安全培训也变得越来越重要。其中&#xff0c;触电急救培训对于保障驾驶员和乘客的安全具有重要意义。传统培训方式存在一些不足&#xff0c;而利用VR技术进行培训则具有很多优势。 利用VR技术开展新能源汽车触电安全演练可以在模…

电脑风扇控制软件Macs Fan Control mac支持多个型号

Macs Fan Control mac是一款专门为 Mac 用户设计的软件&#xff0c;它可以帮助用户控制和监控 Mac 设备的风扇速度和温度。这款软件允许用户手动调整风扇速度&#xff0c;以提高设备的散热效果&#xff0c;减少过热造成的风险。 Macs Fan Control 可以在菜单栏上显示当前系统温…

linux | sed 命令使用 | xargs命令 使用

##################################################### sed命令来自英文词组stream editor的缩写&#xff0c;其功能是利用语法/脚本对文本文件进行批量的编辑操作。sed命令最初由贝尔实验室开发&#xff0c;后被众多Linux系统集成&#xff0c;能够通过正则表达式对文件进行批…

Mysql利用备份数据恢复单表

1、说明 之前的备份是使用Xtrabackup8做的备份 使用了独立表空间(innodb_file_per_table1)&#xff0c;就可以单独恢复这个表。 2、在备份的目录下执行Prepare 根据自己之前备份的目录&#xff0c;选择执行路径 我之前的备份目录是 /tmp/backup/2023-12-16/full cd /tmp/…

虾皮 选品:如何在虾皮平台上进行有效的选品?

在虾皮&#xff08;Shopee&#xff09;这个跨境电商平台上&#xff0c;选品对于卖家来说至关重要。选品决定了店铺的销售额和竞争力。为了帮助卖家进行选品&#xff0c;虾皮平台提供了一些免费的选品工具&#xff0c;如知虾。同时&#xff0c;还有一些第三方选品工具&#xff0…

全国县级行政区点位数据,Shp+excel格式

基本信息. 数据名称: 县级行政区点位 数据格式: Shpexcel 数据时间: 2021年 数据几何类型: 点 数据坐标系: WGS84坐标系 数据来源&#xff1a;网络公开数据 数据字段&#xff1a; 序号字段名称字段说明1xzqhdm_1省代码2xzqhmc_1省名称3xzqhdm_2市代码4xzqhmc_2市代…

pycharm设置自定义的代码颜色

1.最快的方法&#xff0c;选一个自己喜欢的主题&#xff0c;再对细节进行修改&#xff0c;操作如下&#xff0c;file->setting->Editor->ColorScheme->Language Defaults->Scheme。 在选好的主题上自定义自己喜欢的代码颜色&#xff0c;这里本人将自己自定义的函…