WPF Prism框架

Prism 是一个开源框架,专门用于开发可扩展、模块化和可测试的企业级 XAML 应用程序,适用于 WPF(Windows Presentation Foundation)和 Xamarin Forms 等平台。它基于 MVVM(Model-View-ViewModel)设计模式,提供一套丰富的工具和库,能够实现模块化、依赖注入、导航和事件聚合等功能。

Prism 的核心组件包括:

  1. 依赖注入(Dependency Injection):Prism 提供了一个依赖注入容器,可以将应用程序的组件和服务进行解耦,从而提高代码的可测试性和可维护性。
  2. 模块化(Modularity):Prism 支持模块化设计,将应用程序分解成独立的模块,每个模块负责特定的功能,有助于减少应用程序的复杂性,并能够使开发和维护更加容易。
  3. 导航(Navigation):Prism 提供了一个灵活的导航系统,可以定义视图之间的导航路径,并管理视图的生命周期。
  4. 事件聚合器(Event Aggregator):这是一个松散耦合的事件发布/订阅机制,应用程序的不同部分之间进行通信,而不需要直接引用对方。
  5. 命令(Commands):Prism 提供了一种简化的方式来处理用户界面中的命令,如按钮点击事件。
  6. 数据绑定(Data Binding):虽然 Prism 本身不提供数据绑定机制,但它与 WPF 和 Xamarin.Forms 的数据绑定框架紧密集成,可以轻松地将视图模型与视图进行绑定。

安装 Prism

Prism 可以通过 NuGet 包管理器进行安装,主要安装三个 Prism.Core、Prism.Unity、Prism.Wpf。首先创建一个新的 WPF、Xamarin Forms、Uno 或 WinUI 项目,然后打开 NuGet 包管理器,右键点击项目 -> 选择"管理 NuGet 包"。安装 Prism 核心包 Prism.Core,安装容器包 Prism.UnityPrism.DryIoc(根据需求选择),然后安装平台包,例如 WPF 安装 Prism.Wpf

使用 Prism

在 WPF 项目中使用 Prism 时,需要进行以下步骤:

  1. 新建WPF项目:新建一个 WPF 项目,并根据上面完成 Prism 的安装。
  2. 重写 App.xaml:添加命名空间 xmlns:prism="http://prismlibrary.com/" 并继承 PrismApplication,删除 StartupUri="MainWindow.xaml
  3. 修改 App.xaml.cs:继承 PrismApplication,并重写 CreateShell 和 RegisterTypes 方法。CreateShell 方法返回应用程序的主窗口,RegisterTypes 方法用于注册需要的类型。
  4. 修改 MainWindow.xaml:添加命名空间 xmlns:prism="http://prismlibrary.com/" 并设置 prism:ViewModelLocator.AutoWireViewModel="True",Prism 框架会根据规则自动查找该视图相对应 ViewModel。

通过这些步骤,你可以在 WPF 项目中集成 Prism 框架,实现 MVVM 架构和模块化开发。

 priam的依赖注入

Prism 框架中的依赖注入(Dependency Injection)是一种实现控制反转(Inversion of Control, IoC)的机制,它允许开发者将组件和服务的创建和管理从应用程序代码中分离出来,从而提高代码的可测试性和可维护性。以下是 Prism 依赖注入的一些关键点:

  1. PrismApplication 和依赖注入: Prism 项目中的 App 类继承自 PrismApplication,必须重写 CreateShell()RegisterTypes() 方法。RegisterTypes() 方法用于依赖注入容器,该方法使用 IContainerRegistry 类型的对象将用户自定义的对象注入容器。

  2. 内置依赖注入: Prism 源码中已经向 IoC 容器注入了一些核心服务,如 IApplicationProviderIEventAggregatorINavigationService 等,这些服务可以在窗体中通过构造函数直接注入对象。

  3. 自定义服务注入: 如果需要将自定义服务注入 Prism 容器,可以在 App.xaml.cs 中重写 RegisterTypes() 方法,通过 IContainerRegistry 类型的对象将自定义的服务注入 IoC 容器。例如,注册一个 MD5Provider 服务:

    protected override void RegisterTypes(IContainerRegistry containerRegistry)
    {containerRegistry.Register<MD5Provider>();
    }

    然后在需要使用该服务的地方,通过构造函数从 IoC 容器里将对象解析出来:

    public IndexViewModel(IContainerExtension container)
    {MD5Provider provider = container.Resolve<MD5Provider>();
    }
  4. 依赖注入的几种方法

    • Register:每次解析都会创建一个新的实例。
    • RegisterSingleton:整个应用程序生命周期内只创建一个实例(单例)。
    • RegisterScoped:在同一个 Scope 内只初始化一个实例。
  5. 模块化依赖注入: 可以为服务创建一个模块描述文件,继承接口 IModule,在模块描述文件中进行依赖注入。然后在 App.xaml.cs 中重写 ConfigureModuleCatalog 方法加载模块,实现模块的整体注入。

prism的模块化 

Prism 框架的模块化是一种将应用程序分解成独立、可重用模块的设计方法,这样可以提高应用程序的可维护性、可测试性和可扩展性。以下是 Prism 模块化的一些关键概念和步骤:

1. 模块的定义和特点

  • 独立性:每个模块负责特定的功能,并且与其他模块保持低耦合。
  • 可重用性:模块可以独立于主应用程序进行开发、测试和部署。
  • 低耦合:模块之间的依赖关系最小化,有利于维护和扩展。

2. 模块的加载流程

加载模块的流程通常包括以下几个步骤:

  1. 注册模块:在应用程序中注册模块,以便 Prism 框架可以发现和加载它们。
  2. 发现模块:Prism 框架会根据注册信息发现模块。
  3. 加载模块:根据需要加载模块,可以是按需加载或在应用程序启动时加载。
  4. 初始化模块:模块被加载后,会进行初始化,完成模块的设置和配置。

3. 模块的注册方式

Prism 提供了多种模块注册方式:

  • 代码注册:直接在代码中注册模块,这种方式简单直接,易于控制。
  • 目录文件扫描注册:Prism 可以扫描指定目录下的模块并自动注册。
  • 配置文件注册:通过配置文件(如 App.config)来注册模块,这种方式可以在不修改代码的情况下调整模块的加载。

4. 模块的实现

一个典型的 Prism 模块实现包括以下几个部分:

  • 模块类:实现 IModule 接口,定义模块的初始化和注册类型。
  • 视图和视图模型:模块中包含的视图和视图模型,用于实现模块的用户界面和业务逻辑。
  • 服务和依赖注入:在模块中注册服务,并使用依赖注入来管理这些服务。

5. 代码示例

以下是一个简单的 Prism 模块实现示例:

[Module(ModuleName = "MedicineModule", OnDemand = true)]
public class MedicineModule : IModule
{public void OnInitialized(IContainerProvider containerProvider){var regionManager = containerProvider.Resolve<IRegionManager>();regionManager.RegisterViewWithRegion(RegionNames.MedicineMainContentRegion, typeof(MedicineMainContent));}public void RegisterTypes(IContainerRegistry containerRegistry){// 在这里注册模块中需要的服务和类型}
}

在这个示例中,MedicineModule 类标记为一个 Prism 模块,并实现了 IModule 接口。在 OnInitialized 方法中,模块会注册视图到特定的区域。RegisterTypes 方法用于注册模块中需要的服务和类型,例如视图模型、服务等。

 prism的导航

Prism 框架的导航机制是其核心功能之一,它允许应用程序在不同的视图(View)或视图模型(ViewModel)之间进行切换,以实现用户界面的动态更新和功能模块的加载。以下是 Prism 导航机制的一些关键点:

1. 导航的基本概念

Prism 的导航不依赖于页面(Page)实例,而是通过一个唯一的标识符或键(key)来实现松耦合的导航。这意味着在 Prism 中,你不是直接导航到一个视图或视图模型,而是导航到一个代表目标视图的唯一标识符。

2. 定义域(Region)

在 Prism 中,导航通常是基于区域(Region)的概念。你可以使用 ContentControlItemsControl 及其子类来定义一个区域,并为这个区域命名。例如:

<ContentControl Grid.Row="1" Grid.ColumnSpan="2"prism:RegionManager.RegionName="ContentRegion"/>

这样,你就可以在代码中引用这个区域来进行导航。

3. 注册视图

在 Prism 中,你需要在依赖注入(DI)容器中注册视图,以便它们可以被导航到。Prism 提供了 RegisterTypeForNavigation 方法来实现这一点。例如,使用 Unity 容器注册视图:

_unityContainer.RegisterTypeForNavigation<CalendarView>();

这样,CalendarView 就可以被导航到了。

4. 导航操作

Prism 提供了 INavigationService 接口来处理导航请求。你可以通过调用 RequestNavigate 方法来导航到指定的视图。有两种主要的导航方式:

4.1 URI 导航
_regionManager.RequestNavigate("ContentRegion", calendarViewUri);

这里,ContentRegion 是目标区域的名称,calendarViewUri 是一个 Uri 类型的对象,表示需要导航到的视图的名称。

4.2 直接导航

你也可以直接通过视图的名称或自定义的键来导航:

_navigationService.NavigateAsync("MainPage");

这里的 "MainPage" 是注册时使用的键,用于标识要导航到的视图。

5. 自定义注册和导航

Prism 允许你自定义视图的注册和导航。你可以为视图提供一个唯一的键,而不是使用视图的名称作为键:

containerRegistry.RegisterForNavigation<MainPage>("CustomKey");

然后使用这个自定义的键来导航:

_navigationService.NavigateAsync("CustomKey");

这种方式提供了更多的灵活性,允许你根据需要自定义导航逻辑。

6. 跨平台导航

在跨平台应用中,Prism 允许你为不同的平台注册不同的视图,但使用相同的视图模型。这使得你可以为每个平台定制 UI,同时保持业务逻辑的一致性。

 prism的事件聚合器(Event Aggregator)

Prism框架中的事件聚合器(Event Aggregator)是一种松散耦合的事件发布/订阅机制,它允许组件之间进行通信,而不需要直接引用对方。以下是Prism事件聚合器的一些关键特性和使用方法:

1. 松散耦合的通信

事件聚合器允许发布者(publishers)和订阅者(subscribers)通过事件进行通信,而不需要知道对方的存在。这种机制基于事件聚合服务,支持多播发布/订阅功能,即可以有多个发布者触发同一个事件,也可以有多个订阅者监听同一个事件。

2. 类型安全的事件

Prism中的事件是类型安全的,这意味着你可以利用编译时类型检查来在运行应用程序之前检测错误。事件聚合器允许订阅者或发布者定位到特定的EventBase

3. IEventAggregator接口

EventAggregator类作为容器中的服务提供,可以通过IEventAggregator接口检索。事件聚合器负责定位或构建事件,并维护系统中事件的集合:

public interface IEventAggregator
{TEventType GetEvent<TEventType>() where TEventType : EventBase;
}

EventAggregator在首次访问时(如果尚未构建)会构建事件,这减轻了发布者或订阅者需要确定事件是否可用的负担。

4. PubSubEvent类

实际连接发布者和订阅者的工作由PubSubEvent类完成。这是Prism库中唯一实现EventBase类的类。这个类维护订阅者列表,并处理事件分发到订阅者。

5. 创建事件

PubSubEvent<TPayload>是应用程序或模块特定事件的基类。TPayload是事件负载的类型,即发布事件时传递给订阅者的参数。例如,以下代码展示了TickerSymbolSelectedEvent,其负载是一个包含公司符号的字符串:

public class TickerSymbolSelectedEvent : PubSubEvent<string>{}

在复合应用程序中,事件通常在多个模块之间共享,因此它们被定义在一个公共位置,如“Core”或“Infrastructure”项目中。

6. 发布事件

发布事件时,你可以通过EventAggregator获取事件实例,并调用Publish方法来发布事件。例如:

IEventAggregator eventAggregator = container.Resolve<IEventAggregator>();
eventAggregator.GetEvent<TickerSymbolSelectedEvent>().Publish("AAPL");

这样,所有订阅了TickerSymbolSelectedEvent的订阅者都会收到事件,并执行相应的逻辑。

prism的命令(Commands)

Prism框架中的命令(Commands)机制是实现MVVM模式中用户交互与视图模型逻辑分离的核心。以下是Prism命令机制的一些关键点:

1. Prism命令的基础

Prism提供了两种主要的命令类型:

  • DelegateCommand:一个简单的命令实现,适用于单个命令的场景。
  • CompositeCommand:可以将多个命令组合在一起,适用于需要多个命令同时执行的场景。

2. 使用DelegateCommand

2.1. 创建视图模型

在视图模型中创建一个DelegateCommand属性,指向一个方法。例如:

using Prism.Commands;
using Prism.Mvvm;public class MainViewModel : BindableBase
{public DelegateCommand MyCommand { get; private set; }public MainViewModel(){MyCommand = new DelegateCommand(OnMyCommandExecuted);}private void OnMyCommandExecuted(){// 命令执行时的逻辑System.Diagnostics.Debug.WriteLine("Command Executed!");}
}
2.2. 在XAML中绑定命令

在XAML中,可以将命令绑定到控件,如按钮:

<Button Content="Execute Command" Command="{Binding MyCommand}" />

这样,当按钮被点击时,就会执行绑定的命令。

3. 使用带参数的DelegateCommand

可以使用DelegateCommand<T>来处理命令参数。例如:

public DelegateCommand<string> MyParameterizedCommand { get; private set; }public MainViewModel()
{MyParameterizedCommand = new DelegateCommand<string>(OnMyParameterizedCommandExecuted);
}private void OnMyParameterizedCommandExecuted(string parameter)
{// 使用传递的参数System.Diagnostics.Debug.WriteLine($"Command Executed with parameter: {parameter}");
}

在XAML中绑定参数:

<Button Content="Execute with Parameter"Command="{Binding MyParameterizedCommand}"CommandParameter="Hello World" />

这样,当按钮被点击时,就会执行绑定的命令,并传递参数。

4. 使用CompositeCommand

CompositeCommand允许你将多个命令组合在一起,使得它们可以一起执行。例如:

public CompositeCommand MyCompositeCommand { get; private set; }
public DelegateCommand Command1 { get; private set; }
public DelegateCommand Command2 { get; private set; }public MainViewModel()
{MyCompositeCommand = new CompositeCommand();Command1 = new DelegateCommand(OnCommand1Executed);Command2 = new DelegateCommand(OnCommand2Executed);MyCompositeCommand.RegisterCommand(Command1);MyCompositeCommand.RegisterCommand(Command2);
}private void OnCommand1Executed()
{// 命令 1 执行逻辑
}private void OnCommand2Executed()
{// 命令 2 执行逻辑
}

在XAML中使用CompositeCommand

<Button Content="Execute Composite Command" Command="{Binding MyCompositeCommand}" />

这样,当按钮被点击时,就会同时执行Command1Command2

 prism的数据绑定(Data Binding)

Prism框架本身并不提供数据绑定的实现,因为它是建立在WPF、Xamarin.Forms、UWP等框架之上的,这些框架已经内置了数据绑定的功能。Prism通过与这些框架的集成,使得开发者可以利用它们强大的数据绑定机制来构建MVVM(Model-View-ViewModel)模式的应用程序。以下是Prism与数据绑定相关的一些关键点:

1. MVVM模式与数据绑定

MVVM模式是Prism推荐的架构模式,它将用户界面(View)与业务逻辑(ViewModel)分离,并通过数据绑定将它们连接起来。在MVVM中,View只负责显示,ViewModel包含业务逻辑和数据,数据绑定负责在View和ViewModel之间同步数据。

2. WPF中的数据绑定

在WPF中,数据绑定是通过Binding表达式实现的。例如,如果你想将一个文本框(TextBox)的Text属性绑定到ViewModel的Name属性,你可以这样写:

xml

<TextBox Text="{Binding Name}" />

Prism通过ViewModelLocator自动或手动将ViewModel与View关联起来,从而实现数据绑定。

3. Xamarin.Forms中的数据绑定

Xamarin.Forms也支持数据绑定,语法与WPF类似。例如:

xml

<Entry Text="{Binding Name}" />

Prism通过ViewModelLocatorBindingContext将ViewModel与页面(Page)关联起来。

4. Prism的ViewModelLocator

ViewModelLocator是Prism提供的一个附加属性,用于自动将ViewModel与View关联起来。例如,在WPF中,你可以在XAML中这样设置:

xml

<Window ...xmlns:prism="http://prismlibrary.com/"prism:ViewModelLocator.AutoWireViewModel="True"><!-- UI elements -->
</Window>

这样,Prism会自动创建ViewModel实例,并将其设置为View的DataContext

5. 数据转换

Prism与数据绑定框架一起使用时,可以利用数据转换器(Value Converters)来转换绑定的数据。例如,在Xamarin.Forms中,你可以创建一个转换器将布尔值转换为字符串:

csharp

public class BoolToStringConverter : IValueConverter
{public object Convert(object value, Type targetType, object parameter, CultureInfo culture){return (bool)value ? "Yes" : "No";}public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture){throw new NotImplementedException();}
}

然后在XAML中使用这个转换器:

xml

<Label Text="{Binding IsEnabled, Converter={StaticResource BoolToStringConverter}}" />

6. 命令绑定

Prism还支持命令绑定,允许你将UI元素(如按钮)的事件绑定到ViewModel中的命令。例如,在WPF中:

xml

<Button Command="{Binding SaveCommand}" Content="Save" />

这样,当按钮被点击时,就会执行ViewModel中的SaveCommand

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

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

相关文章

智能零售柜商品识别

项目源码获取方式见文章末尾&#xff01; 600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【基于CNN-RNN的影像报告生成】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生成】 4.【CNN模型实现…

SSH远程连接工具详解

SSH远程连接工具指的是基于SSH&#xff08;Secure Shell&#xff09;协议进行远程连接和管理的工具。SSH是一种加密的网络协议&#xff0c;用于在不安全的网络环境中安全地传输数据&#xff0c;并实现远程访问和管理。以下是对远程SSH工具的详细解释&#xff1a; 一、SSH协议概…

卷积层的堆叠、Stacking堆叠法

3个3x3的卷积层串联的效果则相当于1个7x7的卷积层。那为什么选择使用3个3x3的卷积层而不是使用1个7x7的卷积层呢&#xff1f; &#xff08;1&#xff09;3个串联的3x3的卷积层&#xff0c;拥有比1个7x7的卷积层更少的参数&#xff0c;参数量是后者的&#xff08;3x3x3 ) /&…

【模块一】kubernetes容器编排进阶实战之containerd安装及nerdctl客户端⼯具

安装containerd apt/yum安装 #验证仓库版本 [rootk8s-node3 ~]#apt-cache madison containerd containerd | 1.7.12-0ubuntu2~22.04.1 | https://mirrors.aliyun.com/ubuntu jammy-updates/main amd64 Packages containerd | 1.6.12-0ubuntu1~22.04.3 | https://mirrors.aliy…

公司电脑加全屏水印怎么加(怎么打水印满屏)?4个方法精选!包教包会!

在企业管理中&#xff0c;为了保护公司机密信息的安全&#xff0c;给公司电脑添加全屏水印已成为一种常见的安全措施。 全屏水印不仅可以震慑潜在的窥探者&#xff0c;还能在信息不慎泄露时提供追溯线索。 那么&#xff0c;如何给公司电脑添加全屏水印呢&#xff1f; 以下是4…

public or static包下的 html 丢了(404)? 你快回来! 我一人承受不来

没想到吧&#xff0c;我把html还是放到了jar包中&#xff5e; 环境&#xff1a; Spring Boot 版本 2.XJava 版本 1.8.0 及以上 问题&#xff1a; public or static包下的 html 丢了&#xff08;404&#xff09;&#xff1f; 话不多说先上图 我的目录结构是这样的 src └─…

使用多种机器学习调参模型进行二分类建模的全流程,代做分析辅导

使用多种机器学习调参模型进行二分类建模的全流程教程 机器学习全流程分析各个模块用到的总的参数文件 0. 分析参数文件 参数文件名称&#xff1a;total_analysis_params_demo.xlsx &#xff0c;很多分析模块都是这个总的参数文件&#xff0c;我的这个总的参数文件如果有更新…

国家博物馆数据的爬取(包括xlsx文件、csv文件、图片爬取)

1、请求html数据 右键检查这里静态的数据被注释掉了,只能读取一条数据 import json import pandas as pd import requests from bs4 import BeautifulSoup import csv from urllib.parse import quote # 起始网址 header={User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; …

云技术基础介绍

云技术介绍 一、云技术历史 二、云服务 三、公有云服务商 四、云分类 1. 服务层级 IaaS (基础设施即服务) PaaS (平台即服务) SaaS (软件即服务) 2. 云部署模式的分类 公有云 (Public Cloud) 私有云 (Private Cloud) 混合云 (Hybrid Cloud) 社区云 (Community Clo…

常用的c++新特性-->day09

原子变量 C11提供了一个原子类型std::atomic&#xff0c;通过这个原子类型管理的内部变量就可以称之为原子变量&#xff0c;我们可以给原子类型指定bool、char、int、long、指针等类型作为模板参数&#xff08;不支持浮点类型和复合类型&#xff09;。 原子变量会把线程对数据的…

新的服务器Centos7.6 安装基础的环境配置(新服务器可直接粘贴使用配置)

常见的基础服务器配置之Centos命令 正常来说都是安装一个docker基本上很多问题都可以解决了&#xff0c;我基本上都是通过docker去管理一些容器如&#xff1a;mysql、redis、mongoDB等之类的镜像&#xff0c;还有一些中间件如kafka。下面就安装一个 docker 和 nginx 的相关配置…

RAG与知识库搭建,手把手教你构建RAG系统

0. 简介 自从发现可以利用自有数据来增强大语言模型&#xff08;LLM&#xff09;的能力以来&#xff0c;如何将 LLM 的通用知识与个人数据有效结合一直是热门话题。关于使用微调&#xff08;fine-tuning&#xff09;还是检索增强生成&#xff08;RAG&#xff09;来实现这一目标…

【数据结构】10.线索二叉树

一、线索二叉树的产生 采用先序、中序、后序三种方法遍历二叉树后都可以得到一个线性序列&#xff0c;序列上的每一个结点&#xff08;除了第一个和最后一个&#xff09;都有一个前驱和一个后继&#xff0c;但是&#xff0c;这个线性序列只是逻辑的概念&#xff0c;不是物理结…

java实现中小企业的erp系统

项目介绍 技术架构: springboot3jdk17mybatis-plusmysql8kotlinvueuniappelementui等

企业软文营销如何以差异化卖点助力品牌市场曝光?媒介盒子分享

对于市场竞争日益激烈的现下&#xff0c;企业想要获取优势&#xff0c;从市场中脱颖而出并能吸引到更多的消费者&#xff0c;学会创建或找寻到自身的差异点是至关重要的。常言讲“物以稀为贵”&#xff0c;对于消费者而言&#xff0c;品类相同中的品牌需要去以“不同”来获取用…

探索Pillow库:Python图像处理的瑞士军刀

文章目录 **探索Pillow库&#xff1a;Python图像处理的瑞士军刀**1. 背景&#xff1a;为何选择Pillow&#xff1f;2. Pillow是什么&#xff1f;3. 如何安装Pillow&#xff1f;4. 五个简单的库函数使用方法4.1 打开图像4.2 显示图像4.3 转换图像格式4.4 调整图像大小4.5 旋转图像…

快速入门Selenium自动化测试

一、背景与意义 Selenium是常用的Web自动化测试工具&#xff0c;前端开发工程师可以在完成每项开发任务之后&#xff0c;使用Selenuim做一下回归测试&#xff0c;以避免被提BUG太多导致后面做项目总结时太难看。测试工程师学习Selenium时需要掌握很多API接口&#xff0c;例如页…

Java基础-内部类与异常处理

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 一、Java 内部类 什么是内部类&#xff1f; 使用内部类的优点 访问局部变量的限制 内部类和继承 内部…

HCIP—MSTP(多生成树协议)

目录 一、MSTP技术的背景 二 、MSTP&#xff08;多生成树协议&#xff09;的概述 三、MSTP的基本概念 四、MSTP的实验配置 MSTP的引入&#xff1a;单点故障——冗余——二层环路——STP——RSTP——MSTP 一、MSTP技术的背景 单生成树的弊端—部分VLAN路径不同 单生成树的弊…

光控资本:中字头,多股涨停!融资客大举加仓

11月13日&#xff0c;受昨夜外盘心境影响&#xff0c;A股三大指数集体低开&#xff0c;沪指盘中翻红&#xff0c;A50期货指数快速拉升。 当时A股心境并未降温&#xff0c;代表商场急进心境的融资余额数据继续攀升&#xff0c;现在仅次于2015年牛市高点。‍‍‍ 从近期的盘面来…