WPF中的Microsoft XAML Behaviors包功能详解

什么是XAML Behaviors(行为)

XAML Behaviors 提供了一种简单易用的方法,能以最少的代码为 Windows UWP/WPF 应用程序添加常用和可重复使用的交互性。

但是Microsoft XAML Behaviors包除了提供常用的XAML Behaviors之外,还提供了一些Trigger(触发器)以及Trigger对应的Action(动作)。

可以通过一个最简单的示例来感受一下

首先我们引用Microsoft.Xaml.Behaviors.Wpf包,然后添加如下的代码。

在下面的代码中,我们放置了一个按钮,然后为按钮添加了XAML Behavior,当按钮触发Click事件时,调用ChangPropertyAction去改变控件的背景颜色

 1 <Window x:Class="XamlBehaviorsDemo.MainWindow"2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"6         xmlns:local="clr-namespace:XamlBehaviorsDemo"7         xmlns:i="http://schemas.microsoft.com/xaml/behaviors"8         mc:Ignorable="d"9         Title="MainWindow" Height="450" Width="800">
10     <Grid>
11         <Button Width="88" Height="28" Content="Click me">
12             <i:Interaction.Triggers>
13                 <i:EventTrigger EventName="Click">
14                     <i:ChangePropertyAction PropertyName="Background">
15                         <i:ChangePropertyAction.Value>
16                             <SolidColorBrush Color="Red"/>
17                         </i:ChangePropertyAction.Value>
18                     </i:ChangePropertyAction>
19                 </i:EventTrigger>
20             </i:Interaction.Triggers>
21         </Button>
22     </Grid>
23 </Window>

如果没有使用XAML Behavior,我们需要将控件命名,然后在控件的Click事件处理程序中,设置控件的背景颜色 

当然,我们可以通过样式和触发器来实现一样的功能,但这仅限于控件内部,如果要设置其它控件就不行了。而XAML Behavior可以设置目标对象是自身也可以是其它控件。

界面

1  <Button Width="88" Height="28" Content="Click" Margin="10" Name="btn" Click="Button_Click"></Button>

事件处理程序

   private void Button_Click(object sender, RoutedEventArgs e){btn.Background = Brushes.Red;}

说明:

 XAML Behaviors的功能远不止如此,这里只是简单演示。如果不习惯使用XAML Behaviors,也可以继续使用以前的代码。

Microsoft-XAML-Behaviors版本

在.Net Framework时期,XAML Behaviors包含在Blend SDK中,并且需要手动引用 System.Windows.Interactivity.dll

我前面的文章中介绍过如何安装Blend SDK

https://www.cnblogs.com/zhaotianff/p/11714279.html

随着.NET Core的出现,System.Windows.Interactivity.dll中的功能开始放到开源社区,并且改名为Microsoft-XAML-Behaviors。通过nuget包安装。

详情可以参考下面的文章:

https://devblogs.microsoft.com/dotnet/open-sourcing-xaml-behaviors-for-wpf/

以前使用的XAML命名空间是

1 http://schemas.microsoft.com/expression/2010/interactivity

开源以后使用的XAML命名空间是

1 http://schemas.microsoft.com/xaml/behaviors

项目地址:

https://github.com/microsoft/XamlBehaviorsWpf

实现原理

对于实现原理我没有去细看,大概看了一下。假设有如下代码:

1  <Button>
2      <Behaviors:Interaction.Triggers>
3          <Behaviors:EventTrigger EventName="Click">
4              <Behaviors:ControlStoryboardAction Storyboard="{StaticResource StoryboardSample}" ControlStoryboardOption="TogglePlayPause"/>
5          </Behaviors:EventTrigger>
6      </Behaviors:Interaction.Triggers>
7  </Button>

XamlBehaviorsWpf库定义了一个Interaction静态类,在这个类中,定义了两个附加属性,分别 是Triggers和Behaviors。

Triggers是一个TriggerCollection类型,可以存储不同的Trigger。

Behaviors是一个BehaviorCollection类型,可以存储不同的Behavior。

添加Trigger时,Trigger会被添加到TriggerCollection中去。这个Trigger可以是EventTrigger、DataStoreChangedTrigger或DataTrigger等。在Trigger下,实现对应的Action。当Trigger触发时,调用Trigger下的Action。

添加Behavior时,Behavior会被添加到BehaviorCollection中去。XamlBehaviorsWpf提供了DataStateBehavior、FluidMoveBehavior、MouseDragElementBehavior、ConditionBehavior和TranslateZoomRotateBehavior等Behavior。

Trigger和Behavior的区别

触发器

包含一个或多个动作的对象,可根据某些刺激调用这些动作。一种非常常见的触发器是针对事件触发的触发器(EventTrigger)。其他例子可能包括在定时器上触发的触发器,或在抛出未处理异常时触发的触发器。

行为

行为没有调用的概念;它是附加到元素上的东西,用于指定应用程序应在何时做出响应。

常见Trigger的用法

EventTrigger 

监听源上指定事件并在事件触发时触发的触发器。

在使用MVVM模式开发时,需要将事件转换为命令绑定,就可以使用EventTrigger。

用法如下:

下面的代码演示了,当SelectionChanged事件触发时,将会执行Action

1 <ListBox>
2   <i:Interaction.Triggers>
3       <i:EventTrigger EventName="SelectionChanged">
4          ..action...
5       </i:EventTrigger>
6   </i:Interaction.Triggers>
7 </ListBox>

PropertyChangedTrigger

代表当绑定数据发生变化时执行操作的触发器。

用法如下:

下面的代码演示了,当TextBoxText属性发生更改时,将会执行Action

1     <TextBox Text="{Binding TextBoxText,UpdateSourceTrigger=PropertyChanged}">
2         <i:Interaction.Triggers>
3             <i:PropertyChangedTrigger Binding="{Binding TextBoxText}">
4                ...action...
5             </i:PropertyChangedTrigger>
6         </i:Interaction.Triggers>
7     </TextBox>

DataTrigger

代表当绑定数据满足指定条件时执行操作的触发器。

用法如下:

下面的代码演示了,当CheckBox选中/未选中时,将会执行对应的Action

 1  <CheckBox x:Name="checkBox" >2      <i:Interaction.Triggers>3          <i:DataTrigger Binding="{Binding IsChecked, ElementName=checkBox}" Value="False">4             ...选中 action...5          </i:DataTrigger>6          <i:DataTrigger Binding="{Binding IsChecked, ElementName=checkBox}" Value="True">7             ...未选中 action...8          </i:DataTrigger>9      </i:Interaction.Triggers>
13  </CheckBox>

常见Action的用法

ChangePropertyAction

调用时将指定属性更改为指定值的操作。

用法如下:

首先我们在界面上放置一个Rectangle,然后放置两个按钮,当按钮的Click事件触发时,更改Rectangle的Background属性

 1   <Grid>2       <Grid.RowDefinitions>3           <RowDefinition Height="5*"/>4           <RowDefinition Height="*"/>5       </Grid.RowDefinitions>6       <Rectangle x:Name="DataTriggerRectangle" Grid.Row="0" />7 8       <Grid Grid.Row="1">9           <Grid.ColumnDefinitions>
10               <ColumnDefinition Width="*" />
11               <ColumnDefinition Width="*" />
12           </Grid.ColumnDefinitions>
13           <Button x:Name="YellowButton" Content="Yellow" Grid.Column="0">
14               <Behaviors:Interaction.Triggers>
15                   <Behaviors:EventTrigger EventName="Click" SourceObject="{Binding ElementName=YellowButton}">
16                       <Behaviors:ChangePropertyAction TargetObject="{Binding ElementName=DataTriggerRectangle}" PropertyName="Fill" Value="LightYellow"/>
17                   </Behaviors:EventTrigger>
18               </Behaviors:Interaction.Triggers>
19           </Button>
20           <Button x:Name="PinkButton" Content="Pink" Grid.Column="1">
21               <Behaviors:Interaction.Triggers>
22                   <Behaviors:EventTrigger EventName="Click" SourceObject="{Binding ElementName=PinkButton}">
23                       <Behaviors:ChangePropertyAction TargetObject="{Binding ElementName=DataTriggerRectangle}" PropertyName="Fill" Value="DeepPink"/>
24                   </Behaviors:EventTrigger>
25               </Behaviors:Interaction.Triggers>
26           </Button>
27       </Grid>
28 
29   </Grid>

ControlStoryboardAction

调用时将改变目标Storyboard状态的操作,也就是可以控制动画状态。

用法如下:

首先我们放置一个Rectangle

1  <Rectangle x:Name="StoryboardRectangle" StrokeThickness="5" Fill="Pink" Width="100" Stroke="LightYellow" RenderTransformOrigin="0.5,0.5" >
2      <Rectangle.RenderTransform>
3          <ScaleTransform />
4      </Rectangle.RenderTransform>
5  </Rectangle>

然后定义Storyboard,目标对象就是前面定义的Rectangle

 1   <Window.Resources>2       <Storyboard x:Key="StoryboardSample" >3           <DoubleAnimation Duration="0:0:5" To="0.35"4                             Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)"5                             Storyboard.TargetName="StoryboardRectangle" d:IsOptimized="True"/>6           <DoubleAnimation Duration="0:0:5" To="0.35"7                             Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"8                             Storyboard.TargetName="StoryboardRectangle" d:IsOptimized="True"/>9       </Storyboard>
10 
11   </Window.Resources>

再放置一个按钮,使用EventTrigger,当点击时,调用ControlStoryboardAction

1   <Button Content="Start storyboard" HorizontalAlignment="Stretch" Grid.Row="1" VerticalAlignment="Stretch" Margin="0,10,0,10" Width="128" Height="28">
2       <i:Interaction.Triggers>
3           <i:EventTrigger EventName="Click">
4               <i:ControlStoryboardAction Storyboard="{StaticResource StoryboardSample}" ControlStoryboardOption="TogglePlayPause"/>
5           </i:EventTrigger>
6       </i:Interaction.Triggers>
7   </Button>

CallMethodAction

调用指定对象的方法。

用法如下:

首先我们看一下调用ViewModel中方法的示例,添加一个按钮,如下所示:

1  <Button x:Name="button2" Content="调用当前DataContext类方法" HorizontalAlignment="Stretch" Margin="20,3" Grid.Column="1">
2      <i:Interaction.Triggers>
3          <i:EventTrigger EventName="Click" SourceObject="{Binding ElementName=button2}">
4              <i:CallMethodAction TargetObject="{Binding}" MethodName="CallMe"/>
5          </i:EventTrigger>
6      </i:Interaction.Triggers>
7  </Button>

 然后我们在ViewModel中增加一个CallMe函数,为了方便演示,我直接将后台代码类设置为DataContext。

 1   public partial class ActionWindow : Window2   {3       public ActionWindow()4       {5           InitializeComponent();6 7           //设置数据上下文(ViewModel)8           //这里只做演示,直接使用后台类作为ViewModel9           this.DataContext = this;
10       }
11 
12       public void CallMe()
13       {
14           System.Windows.MessageBox.Show("调用了ActionWindow的方法");
15       }
16   }

GoToStateAction

调用时将元素切换到指定 VisualState 的动作。

关于Visual State,可以参考我前面的文章:https://www.cnblogs.com/zhaotianff/p/13254430.html

首先我们定义一个Button控件,并增加两个VisualState。启用和禁用状态,启用时,颜色切换为Pink,禁用时切换为Silver

 1      <Button x:Name="sampleStateButton" Content="示例按钮" VerticalAlignment="Stretch" Height="28" Width="88" Margin="0,0,0,0">2          <Button.Resources>3              <Style TargetType="Button">4                  <Setter Property="Template">5                      <Setter.Value>6                          <ControlTemplate TargetType="Button">7                              <Grid x:Name="BaseGrid" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Pink">8                                  <Label Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"></Label>9                                  <VisualStateManager.VisualStateGroups>
10                                      <VisualStateGroup>
11                                          <VisualState x:Name="Normal">
12                                              <Storyboard>
13                                                  <ColorAnimation Storyboard.TargetName="BaseGrid" Duration="0:0:0.3" Storyboard.TargetProperty="(Grid.Background).(SolidColorBrush.Color)" To="Pink"/>
14                                              </Storyboard>
15                                          </VisualState>
16                                          <VisualState x:Name="Disabled">
17                                              <Storyboard>
18                                                  <ColorAnimation Storyboard.TargetName="BaseGrid" Duration="0:0:0.3" Storyboard.TargetProperty="(Grid.Background).(SolidColorBrush.Color)" To="Silver"/>
19                                              </Storyboard>
20                                          </VisualState>
21                                      </VisualStateGroup>
22                                  </VisualStateManager.VisualStateGroups>
23                              </Grid>
24                          </ControlTemplate>
25                      </Setter.Value>
26                  </Setter>
27              </Style>
28          </Button.Resources>
29      </Button>

然后增加一个CheckBox,当选中时,切换到Disabled状态,未选中时,切换到Normal状态

 1   <CheckBox x:Name="checkBox" Grid.Row="1" Content="启用/禁用" HorizontalAlignment="Center" Margin="0,5">2       <i:Interaction.Triggers>3           <i:DataTrigger Binding="{Binding IsChecked, ElementName=checkBox}" Value="False">4               <i:GoToStateAction StateName="Normal" TargetObject="{Binding ElementName=sampleStateButton}"/>5           </i:DataTrigger>6           <i:DataTrigger Binding="{Binding IsChecked, ElementName=checkBox}" Value="True">7               <i:GoToStateAction StateName="Disabled" TargetObject="{Binding ElementName=sampleStateButton}"/>8           </i:DataTrigger>9       </i:Interaction.Triggers>
10   </CheckBox>

LaunchUriOrFileAction

用于启动进程打开文件或 Uri 的操作。对于文件,该操作将启动默认程序 程序。Uri 将在网络浏览器中打开。

这里我们直接放置一个按钮,当按钮点击 时,打开bing主页

1  <Button x:Name="buttonlaunch" Content="打开Bing" HorizontalAlignment="Stretch" Width="88" Height="28">
2      <i:Interaction.Triggers>
3          <i:EventTrigger EventName="Click" SourceObject="{Binding ElementName=buttonlaunch}">
4              <i:LaunchUriOrFileAction Path="https://www.bing.com" />
5          </i:EventTrigger>
6      </i:Interaction.Triggers>
7  </Button>

PlaySoundAction

播放音频的动作,此操作适用于不需要停止或控制的简短音效。它不支持暂停/继续等操作,仅适用于单次播放。

这是我们放置一个按钮,并嵌入一个音频文件到程序中,当点击按钮的时候,可以播放音频。

注意:音频没播放完成前,退出主窗口,进程不会退出,需要等到音频播放完

1 <Button x:Name="buttonplay" Content="播放音频" Width="88" Height="28">
2     <i:Interaction.Triggers>
3         <i:EventTrigger EventName="Click" SourceObject="{Binding ElementName=buttonplay}">
4             <i:PlaySoundAction Source="../../../Resources/Cheer.mp3" Volume="1.0" />
5         </i:EventTrigger>
6     </i:Interaction.Triggers>
7 </Button>

InvokeCommandAction

执行一个指定的命令。

这个Action是我们最常用的Action,使用MVVM模式进行开发时,需要将控件的事件绑定到Command上,就可以使用InvokeCommandAction。

这里我们放置一个ListBox,并在ViewModel中处理ListBox选择项切换事件。

使用EventTrigger处理SelectionChanged,然后使用InvokeCommandAction,将SelectionChanged事件绑定到OnListBoxSelectionChangedCommand命令。

 1    <ListBox Width="300" Height="200">2        <i:Interaction.Triggers>3            <i:EventTrigger EventName="SelectionChanged">4                <i:InvokeCommandAction Command="{Binding OnListBoxSelectionChangedCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ListBox},Path=SelectedItem}"></i:InvokeCommandAction>5            </i:EventTrigger>6        </i:Interaction.Triggers>7 8        <ListBoxItem>1</ListBoxItem>9        <ListBoxItem>2</ListBoxItem>
10        <ListBoxItem>3</ListBoxItem>
11        <ListBoxItem>4</ListBoxItem>
12    </ListBox>

在ViewModel中定义OnListBoxSelectionChangedCommand命令

 1       public RelayCommand OnListBoxSelectionChangedCommand { get; private set; }2 3       public ActionWindow()4       {5           OnListBoxSelectionChangedCommand = new RelayCommand(OnListBoxSelectionChanged);6       }7 8       public void OnListBoxSelectionChanged(object listBoxItem)9       {
10           var item = listBoxItem as ListBoxItem;
11 
12           if (item != null)
13           {
14               MessageBox.Show(item.Content.ToString());
15           }
16       }
17   }

这样我们在切换列表项时,就会弹窗显示选中项。

RemoveElementAction

调用时将从树中移除目标元素的操作。

 我们放置一个Rectangle和一个Button,当Button按下时,移除这个Rectangle。

 1  <StackPanel>2      <Rectangle x:Name="RectangleRemove" Fill="Pink" Width="120" Height="120"/>3      <Button x:Name="RemoveButton" Content="移除Rectangle" Width="88" Height="28">4          <i:Interaction.Triggers>5              <i:EventTrigger EventName="Click">6                  <i:RemoveElementAction TargetName="RectangleRemove" />7              </i:EventTrigger>8          </i:Interaction.Triggers>9      </Button>
10  </StackPanel>

介绍完Trigger和Action,接下我们看一下Microsoft.Xaml.Behaviors.Wpf包自带的Behavior

常见Behavior的用法

FluidMoveBehavior

观察元素(或元素集)的布局变化,并在需要时将元素平滑移动到新位置的行为。
此行为不会对元素的大小或可见性进行动画调整,只会对元素在其父容器中的偏移量进行动画调整。

例如我们在一个WrapPanel中放置一些控件,并加上FluidMoveBehavior。

这里有几个属性可以注意下:

AppliesTo:表示该行为仅适用于该元素,还是适用于该元素的所有子元素(如果该元素是面板)。

EaseY:用于移动垂直部分的 缓动动画。

EaseX:用于移动水平部分的 缓动动画。

我们看一下使用方法,首先我们在界面上放置一个WrapPanel,然后增加一些子元素(Border),并增加FluidMoveBehavior。

 1  <WrapPanel Width="300" Name="wrap">2      <i:Interaction.Behaviors>3          <i:FluidMoveBehavior Duration="00:00:01" AppliesTo="Children">4              <i:FluidMoveBehavior.EaseX>5                  <BounceEase EasingMode="EaseOut" Bounces="2" />6              </i:FluidMoveBehavior.EaseX>7          </i:FluidMoveBehavior>8      </i:Interaction.Behaviors>9      <Border Width="60" Height="60" BorderThickness="1" BorderBrush="Black" CornerRadius="5" Margin="5"></Border>
10      <Border Width="60" Height="60" BorderThickness="1" BorderBrush="Black" CornerRadius="5" Margin="5"></Border>
11      <Border Width="60" Height="60" BorderThickness="1" BorderBrush="Black" CornerRadius="5" Margin="5"></Border>
12      <Border Width="60" Height="60" BorderThickness="1" BorderBrush="Black" CornerRadius="5" Margin="5"></Border>
13      <Border Width="60" Height="60" BorderThickness="1" BorderBrush="Black" CornerRadius="5" Margin="5"></Border>
14      <Border Width="60" Height="60" BorderThickness="1" BorderBrush="Black" CornerRadius="5" Margin="5"></Border>
15      <Border Width="60" Height="60" BorderThickness="1" BorderBrush="Black" CornerRadius="5" Margin="5"></Border>
16      <Border Width="60" Height="60" BorderThickness="1" BorderBrush="Black" CornerRadius="5" Margin="5"></Border>
17  </WrapPanel>

当窗口打开时,可以看到动画效果。然后我们增加一个按钮,点击 一次面板宽度减少50,因为WrapPanel会根据宽度自动排列元素,所以在宽度变化 时,我们也可以看到元素的动画效果。

1  <Button Content="移除元素" Width="88" Height="28" Click="Button_Click"></Button>
1        private void Button_Click(object sender, RoutedEventArgs e)
2        {
3            this.wrap.Width -= 50;
4        }

运行效果如下:

MouseDragElementBehavior

这个行为可以根据鼠标在元素上的拖动手势重新定位所附元素。

属性:

ConstrainToParentBounds:是否限制在父容器内

X:被拖动元素相对于根元素左侧 X 位置。

Y:X:被拖动元素相对于根元素顶部 Y 位置。 

例如我们在界面上放置一个Rectangle元素,然后使之可以拖动,使用方法如下:

1  <Rectangle Width="50" Height="50" Fill="LightGreen">
2      <i:Interaction.Behaviors>
3          <i:MouseDragElementBehavior></i:MouseDragElementBehavior>
4      </i:Interaction.Behaviors>
5  </Rectangle>

效果如下:

TranslateZoomRotateBehavior

这个行为和MouseDragElementBehavior类似,如果在触控设备上,除了支持移动元素外,还支持手指缩放,如果在不支持触控的设备上,和TranslateZoomRotateBehavior功能一致。

DataStateBehavior

根据条件语句在两种状态之间切换。它表示一种状态,可以根据某些条件是否为真来改变对象的状态。

这个行为也是跟VisualState有关的。

这里我们定义两个State,一个Normal,一个Blue,并增加一个文本框和一个按钮,当文本框数据改变时,改变按钮的状态为Blue。

 1  <StackPanel>2      <TextBox Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Stretch" Margin="5" x:Name="MyText" />3      <Button x:Name="sampleStateButton" Width="88" Height="28">4          <Button.Resources>5              <Style TargetType="Button" >6                  <Setter Property="Template">7                      <Setter.Value>8                          <ControlTemplate TargetType="Button">9                              <Grid x:Name="BaseGrid" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Pink">
10                                  <VisualStateManager.VisualStateGroups>
11                                      <VisualStateGroup>
12                                          <VisualState x:Name="Normal">
13                                              <Storyboard>
14                                                  <ColorAnimation Storyboard.TargetName="BaseGrid" Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)" To="Pink" From="Pink" />
15                                              </Storyboard>
16                                          </VisualState>
17                                          <VisualState x:Name="Blue">
18                                              <Storyboard>
19                                                  <ColorAnimation Storyboard.TargetName="BaseGrid" Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)" To="LightBlue" From="LightBlue" Duration="Forever" />
20                                              </Storyboard>
21                                          </VisualState>
22                                      </VisualStateGroup>
23                                  </VisualStateManager.VisualStateGroups>
24                                  <i:Interaction.Behaviors>
25                                      <i:DataStateBehavior Binding="{Binding Text, ElementName=MyText}" Value="" TrueState="Normal" FalseState="Blue" />
26                                  </i:Interaction.Behaviors>
27                              </Grid>
28                          </ControlTemplate>
29                      </Setter.Value>
30                  </Setter>
31              </Style>
32          </Button.Resources>
33      </Button>
34  </StackPanel>

运行效果如下:

示例代码

下载

参考资料:

https://stackoverflow.com/questions/34017496/what-is-the-difference-between-behaviors-and-event-triggers

https://github.com/microsoft/XamlBehaviorsWpf

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

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

相关文章

运维人员的Go语言学习路线

以下是一份更为详细的适合运维人员的Go语言学习路线图&#xff1a; 一、基础环境搭建与入门&#xff08;第 1 - 2 周&#xff09; 第 1 周 环境搭建 在本地开发机和常用的运维服务器环境&#xff08;如 Linux 系统&#xff09;中安装 Go 语言。从官方网站&#xff08;https://…

设置虚拟机设备的dp和pt

虚拟机有设置px的方式&#xff0c;没有设置dp的方式&#xff0c;举个例子比如设置px为1080*1920虚拟机是有的 此时如果需要375dp宽度的虚拟机&#xff0c; 需要以下步骤 通过日志打印px和density&#xff0c;计算出当前的dp根据density和dp&#xff0c;计算如果需要相应的dp需…

Soildstate渗透测试

第一步&#xff1a;信息收集 Arp-scan -l 扫描本地存活ip&#xff0c;发现可疑ip 192.168.52.140 使用nmap -T4 -sV -sC -p- 192.168.52.140 对目标进行全端口扫描 同时使用dirb和dirsearch对目标网址进行目录爆破&#xff0c;这些网址都可以点进去看看进行一下信息收集看看是…

HTTP cookie与session

telnet命令 telnet 是一个网络协议&#xff0c;用于通过 TCP/IP 网络进行远程登录到服务器。它允许用户在本地计算机上通过网络连接到远程服务器&#xff0c;并在服务器上执行命令 telnet [主机名或IP地址] [端口号]//连接服务器 在 telnet 会话中&#xff0c;Ctrl] 会将你从…

【新年特辑】使用 React + TypeScript 开发新年祝福网页

&#x1f389; 新年将至&#xff0c;我决定开发一个独特的新年祝福网页&#xff0c;让每个人都能创建和分享自己的新年祝福。本文将详细介绍这个项目的开发过程&#xff0c;从技术选型到具体实现&#xff0c;希望能给大家一些启发。 一、项目概述 1.1 项目背景 在这个数字化的…

jmeter分布式启动

https://www.cnblogs.com/qtclm/p/11082081.html 1、代理机&#xff1a;输入“ipconfig”&#xff0c;找到IP地址&#xff0c;在Jmeter/bin/jmeter.properties设置remote host 启动jmeter server 1、控制机&#xff1a;输入“ipconfig”&#xff0c;找到IP地址&#xff0c;在J…

sqoop将MySQL数据导入hive

使用脚本加载数据 MySQL有一张表 hive创建一张相同的表 编写脚本同步数据 [rootmaster sqoop]# vim stu.sh#!/bin/bash SQOOP/usr/local/soft/sqoop-1.4.6/bin/sqoop $SQOOP import --connect jdbc:mysql://192.168.67.100:3306/sqoop \--username root \--password 123456 \-…

【从零开始入门unity游戏开发之——C#篇39】C#反射使用——Type 类、Assembly 类、Activator 类操作程序集

文章目录 前言一、前置知识1、编译器2、程序集&#xff08;Assembly&#xff09;3、元数据&#xff08;Metadata&#xff09; 二、反射1、反射的概念2、反射的作用3、反射的核心Type 类3.1 Type 类介绍3.2 不同方法获取 Type3.3 获取type类型所在的程序集的相关信息 4、反射的常…

【MyBatis源码分析】Spring与MyBatis整合深入解析

&#x1f3ae; 作者主页&#xff1a;点击 &#x1f381; 完整专栏和代码&#xff1a;点击 &#x1f3e1; 博客主页&#xff1a;点击 文章目录 概述SqlSessionFactoryBean详解配置原理 MapperScannerConfigurer 源码分析介绍postProcessBeanDefinitionRegistry 方法 概述 MyBat…

微信小程序几种数据通信方式记录

在微信小程序开发中&#xff0c;组件间的数据传递是一个常见的需求。以下是不同组件间数据传递的方式&#xff0c;根据传递的方向&#xff08;父子、兄弟、跨层级等&#xff09;提供了多种方法。 1. 父组件向子组件传递数据 通过 properties&#xff08;组件属性&#xff09;&…

使用JMeter对Linux生产服务器进行压力测试

安装 JMeter wget https://downloads.apache.org/jmeter/binaries/apache-jmeter-5.4.1.tgz tar -xzf apache-jmeter-5.4.1.tgz cd apache-jmeter-5.4.1创建 JMeter 脚本 设置中文 选择Options—>Choose Language—>选择其他语言&#xff08;例如&#xff1a;Chinese&am…

STM32-笔记20-测量按键按下时间

1、按键按下的时间-思路 我们先检测下降沿信号&#xff0c;检测到以后&#xff0c;在回调函数里切换成检测上升沿信号&#xff0c;当两个信号都检测到的时候&#xff0c;这段时间就是按键按下的时间&#xff0c;如图所示&#xff1a;>N*(ARR1)CCRx的值 N是在这段时间内&…

2024年12月CCF-GESP编程能力等级认证Scratch图形化编程四级真题解析

本文收录于《Scratch等级认证CCF-GESP图形化真题解析》专栏,专栏总目录:点这里,订阅后可阅读专栏内所有文章。 一、单选题(共 10 题,每题 2 分,共 30 分) 第 1 题 2024 年 10 月 8 日,诺贝尔物理学奖“意外地”颁给了两位计算机科学家约翰霍普菲尔德(John J. Hopfie…

常见协议的高危软件漏洞信息

HTTP 协议 协议 | 软件 | 漏洞编号 | 漏洞描述 Apache Log4j CVE-2021-45105 | Apache Log4j拒绝服务攻击漏洞 XWiki Platform CVE-2023-26477 | XWiki Platform存在安全漏洞&#xff0c;该漏洞源于可以通过URL请求参数结合其他参数注入任意脚本宏 Microsoft Windows CVE-20…

CPT203 Software Engineering 软件工程 Pt.2 敏捷方法和需求工程(中英双语)

文章目录 3. Aglie methods&#xff08;敏捷方法&#xff09;3.1 Aglie methods&#xff08;敏捷方法&#xff09;3.1.1 特点3.1.2 优点3.1.3 缺点3.1.4 原则3.1.5 计划驱动与敏捷方法的对比 3.2 Scrum3.2.1 Scrum roles3.2.2 Scrum Activities and Artifacts3.2.2.1 Product B…

攻防靶场(29):目录权限和文件权限 ICMP

目录 1. 侦查 1.1 收集目标网络信息&#xff1a;IP地址 1.2 主动扫描&#xff1a;扫描IP地址段 1.3 搜索目标网站 2. 初始访问 2.1 利用面向公众的应用 3. 权限提升 3.1 有效账户&#xff1a;本地账户 3.2 滥用特权控制机制&#xff1a;Sudo和Sudo缓存 靶场下载地址&#xff1a…

libmodbus源码中重要的两个结构体讲解

文章目录 一、libmodbus重要数据结构讲解**1. 结构体 `_modbus`**定义成员解析小结**2. 结构体 `_modbus_backend`**定义成员解析小结**3. 两者关系和工作流程****关系****工作流程**一、libmodbus重要数据结构讲解 这两个结构体是 libmodbus 的核心,定义了 Modbus 通信上下文…

Spring自动化创建脚本-解放繁琐的初始化配置!!!(自动化SSM整合)

一、实现功能(原创&#xff0c;转载请告知) 1.自动配置pom配置文件 2.自动识别数据库及数据表&#xff0c;创建Entity、Dao、Service、Controller等 3.自动创建database.properties、mybatis-config.xml等数据库文件 4.自动创建spring-dao.xml spring-mvc.xml …

【详解】AndroidWebView的加载超时处理

Android WebView的加载超时处理 在Android开发中&#xff0c;WebView是一个常用的组件&#xff0c;用于在应用中嵌入网页。然而&#xff0c;当网络状况不佳或页面加载过慢时&#xff0c;用户可能会遇到加载超时的问题。为了提升用户体验&#xff0c;我们需要对WebView的加载超时…

java开发中注解汇总​​

注解作用位置注意mybatis Data Getter Setter ToString EqualsAndHashCode AllArgsConstructor NoArgsConstructor Data 代替&#xff1a;无参构造&#xff0c;get&#xff0c;set&#xff0c;toString&#xff0c;hashCode&#xff0c;equals Getter Setter 可放在类和方法上&…