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 ...
随机推荐
- SQL Server 字段类型 decimal(18,6)小数点前是几位?记一次数据库SP的BUG处理
原文:SQL Server 字段类型 decimal(18,6)小数点前是几位?记一次数据库SP的BUG处理 SQL Server 字段类型 decimal(18,6)小数点前是几位? 不可否认,这是 ...
- C# 引用类型与值类型的区别
//引用类型(使用了class) class SomeRef{public Int32 x;} //值类型(使用了struct) struct SomeVal{public Int32 x;} sta ...
- 我的学习笔记_Windows_HOOK计划 2009-12-03 11:19
一.什么是HOOK? "hook"这个单词的意思是"钩子","Windows Hook"是Windows消息处理机制的一个重要扩展,程序猿能 ...
- http1.0 和 http1.1 区别
http1.0 和 http1.1 主要区别 1.背景 KeepAlive是就是通常所称的长连接.KeepAlive带来的好处是可以减少tcp连接的开销,这对于短response body的请求效 ...
- 将 Android* x86 NDK 供 Eclipse* 而移植 NDK 演示示例应用程序
目标 面向 Eclipse (ADT) 的 Android 插件如今支持基于 NDK 的应用开发. 其可自己主动生成项目和构件文件以及代码存根.并可集成到整个 Android 应用开发中(构建原生库. ...
- 兔子--Fragment与ViewPager要切换滑动效果
效果图: 文件夹结构: 代码分析: MainActivity.java package com.example.myfragment; /** * @author Arthur Lee * @time ...
- JS伪3D 图形透视效果
本文地址:http://blog.csdn.net/ei__nino/article/details/9243331 本来是想实现多个圆片的透视效果,对于运算都是测试得出的.不是严谨的数学计算. 使用 ...
- 重新想象 Windows 8 Store Apps (14) - 控件 UI: RenderTransform, Projection, Clip, UseLayoutRounding
原文:重新想象 Windows 8 Store Apps (14) - 控件 UI: RenderTransform, Projection, Clip, UseLayoutRounding [源码下 ...
- 成都传智职工high翻竞赛场
日前,由石羊街道总工会.天府新谷园区党委联合主办的“2013年职工趣味竞赛”盛大开幕.传智播客成都java培训中心员工积极参与,活跃在各大项目的比赛中,员工们用笑脸.身影告诉大家:竞赛场上,我们hig ...
- BAE3.0搭建wordpress注意
仅仅是mark一个注意的点,数据库连接时,主机是: /** MySQL主机 */ define('DB_HOST', 'sqld.duapp.com:4050');