WPF学习(9)样式和行为
在asp.net世界中,我们的美工人员会为我们准备好静态页面,它注意包括三个部分:html、css和js。而在WPF世界里,也同样有着类似这三个部分的静态页面:Xaml、Style和Behaviors,当然,它们和前面三者的作用并不对等。Style几乎完成了css和js的功能,而Sliverlight 3中引入的Behaviors(封装到Expression Blend 3中和Expression Blend 3 SDK中)只是为了方便代码的复用,我们在后面详细来说。本文主要从Style样式和Behaviors行为两个方面来讲。
1.Style
先来看看Style类的属性:
1.1Setters
Setters是Style默认的内容属性,是Setter对象或者EventSetter对象的集合,所以可以省略Style.Setters而直接使用Setter或EventSetter。
Setter是用于设置属性值的,这个属性还得是依赖属性。EventSetter是自动关联事件处理程序的。举个例子:
xaml代码:
- <Window x:Class="StyleDemo.MainWindow"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- Title="MainWindow" Height="350" Width="525">
- <Window.Resources>
- <Style x:Key="labelStyle" TargetType="Label">
- <Setter Property="Foreground">
- <Setter.Value>Red</Setter.Value>
- </Setter>
- <Setter Property="Control.FontSize" Value="28" />
- <Setter Property="Slider.FontFamily" Value="宋体" />
- <EventSetter Event="MouseMove" Handler="Label_MouseMove" />
- </Style>
- <Style x:Key="buttonStyle">
- <Setter Property="Button.FontSize" Value="22" />
- <Setter Property="Button.FontFamily" Value="SimSun" />
- <Setter Property="Button.FontWeight" Value="Bold" />
- <Setter Property="Button.Background" Value="Red" />
- </Style>
- </Window.Resources>
- <Grid>
- <StackPanel>
- <Label Content="Hi,WPF" Style="{StaticResource labelStyle}" />
- <TextBlock Text="Sliverlight 5" Style="{StaticResource buttonStyle}"/>
- <Button Content="Click">
- <Button.Style>
- <Style>
- <Setter Property="Control.Background">
- <Setter.Value>
- <LinearGradientBrush>
- <GradientStop Offset="0" Color="Red" />
- <GradientStop Offset="0.5" Color="Blue" />
- <GradientStop Offset="1" Color="Yellow" />
- </LinearGradientBrush>
- </Setter.Value>
- </Setter>
- </Style>
- </Button.Style>
- </Button>
- <Button Content="DoubleClick" Style="{StaticResource buttonStyle}"/>
- </StackPanel>
- </Grid>
- </Window>
cs代码:
- private void Label_MouseMove(object sender, MouseEventArgs e)
- {
- MessageBox.Show("Mouse Move!!");
- }
看下效果:
需要说明一下几点:
1)以资源的形式要比内嵌的形式更具灵活性
2)在内嵌的形式中,设置属性值时,要么指定TargetType,要么使用Class.Property的形式
3)"<Setter Property="Control.Background">...</setter>"与"<Setter Property="Background">...</setter>"的区别在于,前者先去设置Control的Backgroud属性,然后应用该样式的控件继承,而后者直接去设置应用该样式的控件的属性
1.2Triggers
Triggers,即为触发器,使用它可以自动完成简单的样式改变。主要有以下几种触发器:
具个例子,一并说明下这五种触发器:
xaml代码:
- <Window x:Class="StyleDemo.Window1"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:local="clr-namespace:StyleDemo"
- Title="Window1" Height="300" Width="300">
- <Window.Resources>
- <!--Trigger属性触发器-->
- <Style x:Key="triggerKey">
- <Style.Triggers>
- <Trigger Property="Control.IsMouseOver" Value="true">
- <Setter Property="Control.Foreground" Value="Red" />
- <Setter Property="Control.FontSize" Value="20" />
- </Trigger>
- </Style.Triggers>
- </Style>
- <!--MultiTrigger多条件属性触发器-->
- <Style x:Key="multiTriggerKey">
- <Style.Triggers>
- <MultiTrigger>
- <MultiTrigger.Conditions>
- <Condition Property="Control.Foreground" Value="Red"></Condition>
- <Condition Property="Control.IsMouseOver" Value="true"></Condition>
- </MultiTrigger.Conditions>
- <!--<MultiTrigger.EnterActions>
- <BeginStoryboard>
- <Storyboard>
- <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(FrameworkElement.Width)">
- <SplineDoubleKeyFrame KeyTime="00:00:00.0020000" Value="0"/>
- <SplineDoubleKeyFrame KeyTime="00:00:00.3450000" Value="95"/>
- </DoubleAnimationUsingKeyFrames>
- <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(FrameworkElement.Height)">
- <SplineDoubleKeyFrame KeyTime="00:00:00.0020000" Value="0"/>
- <SplineDoubleKeyFrame KeyTime="00:00:00.3450000" Value="54"/>
- </DoubleAnimationUsingKeyFrames>
- </Storyboard>
- </BeginStoryboard>
- </MultiTrigger.EnterActions>-->
- <MultiTrigger.Setters>
- <Setter Property="Control.ToolTip" Value="Background:Red,FontSize" />
- </MultiTrigger.Setters>
- </MultiTrigger>
- </Style.Triggers>
- </Style>
- <!--EventTrigger事件触发器-->
- <Style x:Key="eventTriggerKey">
- <Style.Triggers>
- <EventTrigger RoutedEvent="Mouse.MouseEnter">
- <EventTrigger.Actions>
- <BeginStoryboard>
- <Storyboard>
- <DoubleAnimation Duration="0:0:0.2" Storyboard.TargetProperty="FontSize" To="22" />
- </Storyboard>
- </BeginStoryboard>
- </EventTrigger.Actions>
- </EventTrigger>
- <EventTrigger RoutedEvent="Mouse.MouseLeave">
- <EventTrigger.Actions>
- <BeginStoryboard>
- <Storyboard>
- <DoubleAnimation Duration="0:0:0.2" Storyboard.TargetProperty="FontSize" />
- </Storyboard>
- </BeginStoryboard>
- </EventTrigger.Actions>
- </EventTrigger>
- </Style.Triggers>
- </Style>
- <!--DataTrigger数据触发器-->
- <local:L2BConverter x:Key="l2bCvt" />
- <Style x:Key="dataTriggerKey">
- <Style.Triggers>
- <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self},Path=Text.Length,Converter={StaticResource l2bCvt}}" Value="false">
- <Setter Property="Control.BorderBrush" Value="Red" />
- <Setter Property="Control.BorderThickness" Value="1" />
- </DataTrigger>
- </Style.Triggers>
- </Style>
- <!--MultiDataTrigger多条件数据触发器-->
- <local:L2BConverter x:Key="l2bCvt1" />
- <local:S2BConverter x:Key="s2bCvt" />
- <Style x:Key="multiDataTriggerKey">
- <Style.Triggers>
- <MultiDataTrigger>
- <MultiDataTrigger.Conditions>
- <Condition Binding="{Binding RelativeSource={RelativeSource Self},Path=Text.Length,Converter={StaticResource l2bCvt1}}" Value="false" />
- <Condition Binding="{Binding RelativeSource={RelativeSource Self},Path=Text,Converter={StaticResource s2bCvt}}" Value="false" />
- </MultiDataTrigger.Conditions>
- <MultiDataTrigger.Setters>
- <Setter Property="Control.BorderBrush" Value="Red" />
- <Setter Property="Control.BorderThickness" Value="1" />
- </MultiDataTrigger.Setters>
- </MultiDataTrigger>
- </Style.Triggers>
- </Style>
- </Window.Resources>
- <Grid>
- <StackPanel>
- <Label Style="{StaticResource triggerKey}" Content="Hi,WPF" />
- <TextBlock Style="{StaticResource multiTriggerKey}" Foreground="Red" FontSize="16" Text="RIA World" />
- <Button x:Name="button" Style="{StaticResource eventTriggerKey}" Content="MouseEnter" />
- <TextBox Style="{StaticResource dataTriggerKey}"/>
- <TextBox Style="{StaticResource multiDataTriggerKey}"/>
- </StackPanel>
- </Grid>
- </Window>
用到的两个Converter:
字符串长度转布尔类:
- public class L2BConverter:IValueConverter
- {
- public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
- {
- return (int)value > ? true : false;
- }
- public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
- {
- return null;
- }
- }
字符串转布尔类
- class S2BConverter:IValueConverter
- {
- public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
- {
- Regex regex = new Regex(@"^\d*$");
- return !regex.IsMatch(value.ToString());
- }
- public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
- {
- throw new NotImplementedException();
- }
- }
效果大家可以copy代码运行看看。
1.3Resources
Style的Resources属性是ResourceDictionary类型,可以放一些在style中需要共享的对象资源。来看个例子:
xaml代码:
- <Window x:Class="StyleDemo.Window2"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- Title="Window2" Height="300" Width="300">
- <Window.Resources>
- <Style x:Key="buttonKey">
- <Style.Resources>
- <LinearGradientBrush x:Key="lgbKey">
- <GradientStop Offset="0" Color="Red" />
- <GradientStop Offset="0.5" Color="Green" />
- <GradientStop Offset="1" Color="Blue" />
- </LinearGradientBrush>
- </Style.Resources>
- <Setter Property="Control.Background" Value="{StaticResource lgbKey}" />
- </Style>
- </Window.Resources>
- <Grid>
- <StackPanel>
- <Button Content="button" Style="{StaticResource buttonKey}" />
- </StackPanel>
- </Grid>
- </Window>
效果如下:
1.4BaseOn
Style的BaseOn属性,可以实现Style的继承,从而实现多层样式。来看个简单的例子:
xaml代码:
- <Window x:Class="StyleDemo.Window2"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- Title="Window2" Height="300" Width="300">
- <Window.Resources>
- <Style x:Key="buttonKey">
- <Style.Resources>
- <LinearGradientBrush x:Key="lgbKey">
- <GradientStop Offset="0" Color="Red" />
- <GradientStop Offset="0.5" Color="Green" />
- <GradientStop Offset="1" Color="Blue" />
- </LinearGradientBrush>
- </Style.Resources>
- <Setter Property="Control.Background" Value="{StaticResource lgbKey}" />
- <Setter Property="Control.FontFamily" Value="Times New Roman" />
- <Setter Property="Control.FontWeight" Value="Bold" />
- <Setter Property="Control.FontSize" Value="18" />
- </Style>
- <Style x:Key="buttonInheritKey" BasedOn="{StaticResource buttonKey}">
- <Setter Property="Control.Foreground" Value="DarkOrange" />
- <Setter Property="Control.FontSize" Value="22" />
- </Style>
- </Window.Resources>
- <Grid>
- <StackPanel>
- <Button Content="button" Style="{StaticResource buttonKey}" />
- <Button Content="button1" Style="{StaticResource buttonInheritKey}" />
- </StackPanel>
- </Grid>
- </Window>
效果图如下:
1.5TargetType
这个属性,指定的是应用该Style的控件的类型。我们以一个例子为切入点来说明下:
xaml代码:
- <Window x:Class="StyleDemo.Window3"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- Title="Window3" Height="300" Width="300">
- <Window.Resources>
- <!--TargetType属性-->
- <Style TargetType="Button">
- <Setter Property="Foreground" Value="Yellow" />
- <Setter Property="FontSize" Value="28" />
- </Style>
- <Style x:Key="buttonKey">
- <Setter Property="Control.FontSize" Value="12" />
- </Style>
- </Window.Resources>
- <Grid>
- <StackPanel>
- <TextBox />
- <Button Content="Click" />
- <Button Content="Click2" Style="{StaticResource buttonKey}"/>
- </StackPanel>
- </Grid>
- </Window>
效果如下:
首先,你可能会奇怪,指定了TargetType的Style这里没有x:key来标识该资源,这是因为xaml解析器会自动以其对象类型来当作它的key,类似这样:x:key="{x:Type Button}"。
另外,需要说明一下几点:
1)设置了TargetType类型的Style会应用该种类型的所有控件。
2)如果某该类型控件另外还设置了Style,会进行Merge的操作(由StaticResource或DynamicResource和TargetType确定的Style和ThemeStyle的合并)。StaticResource或DynamicResource和TargetType相同的Setter属性值,前者优先级高,不同的Setter属性值均起作用。
2.Behaviors
Style提供了重用一组属性设置的方法,为帮助构建统一良好的界面迈出了重要的一步,但是,还是有很多的限制,比如对于动画的支持不够。我们知道,通常要设计一个动画效果,需要很多的xaml代码。而这样的动画也经常会在其他的地方使用,但是我们却不得不复制那一大块代码,为了DRY,微软在Expression Blend 3推出了Behaviors行为的特性。
首先,我们需要了解Behaviors这样几个关键点:
1)Behaviors可复用代码集合(UI功能),可以被任何对象附加使用
2)设计人员和开发人员只需要将它附加到元素上,而无需写任何的逻辑代码
3)一个Behaviors可以被多个对象元素同时使用
与Behaviors相关的程序集:
System.Windows.Interactivity.dll,该链接库定义了Behaviors(行为)基础类,有了该链接库支持,即可支持Behaviors(行为);
Microsoft.Expression.Interactions.dll,该链接库提供了一些扩展行为类库,以及一些Action和Trigger类,作为演示实例;
Behaviors主要包括Trigger、Action和Behavior三个部分。需要注意的是,这里的Trigger和WPF的Trigger并不完全一样,可以同时使用它们。
IAttachObject接口的定义很简单:
- // 摘要:
- // 供可以附加到另一个对象的对象使用的接口。
- public interface IAttachedObject
- {
- // 摘要:
- // 获得关联的对象。
- //
- // 备注:
- // 代表此实例附加到的对象。
- DependencyObject AssociatedObject { get; }
- // 摘要:
- // 附加到指定的对象。
- //
- // 参数:
- // dependencyObject:
- // 要附加到的对象。
- void Attach(DependencyObject dependencyObject);
- //
- // 摘要:
- // 将此实例与其关联的对象分离。
- void Detach();
- }
AssociatedObject是一个只读的依赖对象属性,它指定行为的应用者。
2.1自定义一个Behavior
下面我们来自己定义一个Behaviors看看,要实现的效果是在Canvas中的控件可任意拖动:
先定义一个继承自Behavior<UIElement>的DragInCanvasBehavior类
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Interactivity;
- using System.Windows.Media;
- namespace CustomBehaviorsLib
- {
- public class DragInCanvasBehavior:Behavior<UIElement>
- {
- protected override void OnAttached()
- {
- base.OnAttached();
- //Hook up event handlers
- this.AssociatedObject.MouseLeftButtonDown += AssociatedObject_MouseLeftButtonDown;
- this.AssociatedObject.MouseMove += AssociatedObject_MouseMove;
- this.AssociatedObject.MouseLeftButtonUp += AssociatedObject_MouseLeftButtonUp;
- }
- void AssociatedObject_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
- {
- if (isDragging)
- {
- AssociatedObject.ReleaseMouseCapture();
- isDragging = false;
- }
- }
- void AssociatedObject_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
- {
- if (isDragging)
- {
- Point point = e.GetPosition(canvas);
- AssociatedObject.SetValue(Canvas.TopProperty, point.Y-mouseOffset.Y);
- AssociatedObject.SetValue(Canvas.LeftProperty, point.X - mouseOffset.X);
- }
- }
- private Canvas canvas;
- private bool isDragging = false;
- private Point mouseOffset;
- void AssociatedObject_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
- {
- if (canvas == null)
- canvas = (Canvas)VisualTreeHelper.GetParent(this.AssociatedObject);
- isDragging = true;
- mouseOffset = e.GetPosition(AssociatedObject);
- AssociatedObject.CaptureMouse();
- }
- protected override void OnDetaching()
- {
- base.OnDetaching();
- //detach event handlers
- this.AssociatedObject.MouseLeftButtonDown += AssociatedObject_MouseLeftButtonDown;
- this.AssociatedObject.MouseMove += AssociatedObject_MouseMove;
- this.AssociatedObject.MouseLeftButtonUp += AssociatedObject_MouseLeftButtonUp;
- }
- }
- }
然后在window4.xaml中添加对DragInCanvasBehavior类所在类库的引用,同时添加System.Window.Interactivity.dll的引用。
xaml代码如下:
- <Window x:Class="StyleDemo.Window4"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
- xmlns:custom="clr-namespace:CustomBehaviorsLib;assembly=CustomBehaviorsLib"
- Title="Window4" Height="300" Width="300">
- <Grid>
- <Canvas x:Name="p_canvas">
- <Canvas x:Name="c_canvas1" Width="100" Height="100" Background="Yellow" />
- <Canvas x:Name="c_canvas2" Width="100" Height="100" Canvas.Left="110" Background="Red">
- <i:Interaction.Behaviors>
- <custom:DragInCanvasBehavior />
- </i:Interaction.Behaviors>
- </Canvas>
- <Canvas x:Name="c_canvas3" Width="100" Height="100" Canvas.Top="110" Background="Blue" />
- </Canvas>
- </Grid>
- </Window>
通过向BehaviorCollection类型的Interaction.Behaviors附加属性添加DragInCanvasBehavior实例。
效果如下:
这里只是给红色的Canvas添加了DragInCanvasBehavior,所以只有红色的Canvas可以Drag。
Expression Blend 3 以及之后的版本(4和4.5)都有Behaviors提供了很好的支持,内部提供了好多封装好的Behaviors。况且,使用blend可以很方便简单的使用它。
2.2Expression Blend中Behaviors
Expression Blend是和Visual Studio配套使用的,也就是说对应的采用的是相同的解决方案文件格式,Blend 3对应VS2008,Blend 4对应VS2010,Blend 5对应VS2012。
这里提供许多现成的行为,也包含自定义的Behaviors。用法基本类似,这里我们以MouseDragElementBehavior为例,来介绍下在Expression Blend中对Behaviors的使用。
先向界面拖放一个主Canvas,里面放三个子Canvas,背景颜色分别设为Yello、Red和Blue。然后将MouseDragElementBehavior拖放到红色的子Canvas上面,代码便自动完成了,实现了与上面相同的效果,及其方便快捷。
有关Expression Blend的使用技巧,将会单独来讲,在后面模板和动画的学习中还将会提到。
WPF学习(9)样式和行为的更多相关文章
- WPF自定义控件与样式(3)-TextBox & RichTextBox & PasswordBox样式、水印、Label标签、功能扩展
一.前言.预览 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要是对文本 ...
- WPF自定义控件与样式(1)-矢量字体图标(iconfont)
一.图标字体 图标字体在网页开发上运用非常广泛,具体可以网络搜索了解,网页上的运用有很多例子,如Bootstrap.但在C/S程序中使用还不多,字体图标其实就是把矢量图形打包到字体文件里,就像使用一般 ...
- WPF自定义控件与样式(2)-自定义按钮FButton
一.前言.效果图 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 还是先看看效果 ...
- WPF自定义控件与样式(15)-终结篇 & 系列文章索引 & 源码共享
系列文章目录 WPF自定义控件与样式(1)-矢量字体图标(iconfont) WPF自定义控件与样式(2)-自定义按钮FButton WPF自定义控件与样式(3)-TextBox & Ric ...
- WPF自定义控件与样式(4)-CheckBox/RadioButton自定义样式
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: Che ...
- WPF自定义控件与样式(5)-Calendar/DatePicker日期控件自定义样式及扩展
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: 日历控 ...
- WPF自定义控件与样式(6)-ScrollViewer与ListBox自定义样式
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: Scr ...
- WPF自定义控件与样式(7)-列表控件DataGrid与ListView自定义样式
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: Dat ...
- WPF自定义控件与样式(8)-ComboBox与自定义多选控件MultComboBox
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: 下拉选 ...
- WPF自定义控件与样式(9)-树控件TreeView与菜单Menu-ContextMenu
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: 菜单M ...
随机推荐
- 第一章 andrid visdio 安装
第一章 andrid visdio 安装与环境搭建 一.Android Studio简介 Android Studio是Google新发布的Android应用程序开发环境,Android Stud ...
- Qt--将Qt 动态链接生成的exe及依赖dll打包方法
Qt静态编译链接生成的exe文件,不需依赖dll,可以独立运行,发布很方便. 但绝大多数用的都是Qt开源版本,如果用静态链接,会有些限制. 方法之一,就是用动态编译,然后把exe和需要的dll整合成一 ...
- 利用 C++ 单向链表实现队列
利用C++ 单向链表实现数据结构队列,其实和上一篇基本内容相同,仅仅是插入的时候在链表的尾部插入,取元素都是一样的,都从头部取. #pragma once #include "stdio.h ...
- linux下安装cmake和mysql遇到的问题总结
首先是在安装cmake的过程中遇到的问题: 1.開始使用yum命令安装时,不知道为什么一直不行,然后就准备wget 来先下载压缩包,再手动编译. 因为网络限制,wget不能下载外网的东西一直显示con ...
- hdu1754(splay)
给n个数,有两种操作 Q a b 询问区间[a,b]的最大值, U a b 将第a个数的值改成b splay树的中序遍历是我们所维护的序列.如果要询问区间[a,b]的最大值,那么只要将第a ...
- 新型I/O架构引领存储之变(四)
新型I/O架构引领存储之变(四) 作者:廖恒 应对挑战--商务及技术考量 本文前面的部分分析了砖块模式与生俱来的总拥有成本(TCO)过高的问题.为了战胜这一挑战,超大规模数据中心的运营者须要从两个不同 ...
- jsp的原则执行
什么时候server一对JSP页面运行时,第一个请求,server向上JSP引擎首先JSP页的文件翻译成Java文件.那么这Java文件编译的字节码文件..而当这个JSP页面再次被请求运行时,JSP引 ...
- 远程方法调用(RMI)原理与示例 (转)
RMI介绍 远程方法调用(RMI)顾名思义是一台机器上的程序调用另一台机器上的方法.这样可以大致知道RMI是用来干什么的,但是这种理解还不太确切.RMI是Java支撑分布式系统的基石,例如著名的EJB ...
- Python编程预约参观北京行动纲要
通过Python程序来模拟一个统一平台预约参观北京,包含验证码识别.登陆.据医院.时间.有关主管部门号等查询. 此程序仅供学习使用,请勿用于其他用途. 1.验证码图片 def getCodePic() ...
- HDU 2063 过山车 二分图题解
一个男女搭配的关系图,看能够凑成多少对,基本和最原始的一个二分图谜题一样了,就是 一个岛上能够凑成多少对夫妻的问题. 所以是典型的二分图问题. 使用匈牙利算法,写成两个函数,就很清晰了. 本程序还带分 ...