html5的placeholder可以为文本框提供更多信息,让软件更容易操作.。
虽然winform里面没有占位符,但是可以通过事件巧妙地将其创建出来。
下面是效果图:
代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
namespace Style
{
/// <summary>
/// html里面的占位符, 可增加提示信息, 提升软件的易用性。
/// </summary>
public class Placeholder
{
#region 私有字段
/// <summary>
/// 文本框和它绑定的占位符 parentAndChilds
/// </summary>
static Dictionary<Control, Label> relevanceDic = new Dictionary<Control, Label>();
/// <summary>
/// 占位符和它的各语言文本
/// </summary>
static Dictionary<Control, List<String>> plhs = new Dictionary<Control, List<String>>();
/// <summary>
/// 命名序号
/// </summary>
static int nameNumber;
/// <summary>
/// 默认显示哪组占位符
/// </summary>
static ushort defaultIndex;
#endregion
#region 构造方法
#endregion
#region 属性
/// <summary>
/// 占位符的命名前缀
/// </summary>
public static String placeHolderName = "placeHolder";
/// <summary>
/// 默认显示哪个占位符
/// </summary>
public static ushort Index
{
get { return Placeholder.defaultIndex; }
set { Placeholder.defaultIndex = value; }
}
#endregion
#region 公共方法
/// <summary>
/// 为一个文本框设置一个多语言占位符, 需要调用Refresh方法刷新且显示
/// </summary>
/// <param name="textbox">文本框</param>
/// <param name="languageTxt">语言集合</param>
public static void setPlh(Control textbox, params String[] languageTxt)
{
//如果控件已经存在占位符,则替换
if (relevanceDic.ContainsKey(textbox))
{
Label oldPlaceolder = relevanceDic[textbox];
plhs.Remove(oldPlaceolder);
relevanceDic.Remove(textbox);
oldPlaceolder.Dispose();
}
else {
//增加相应事件,保证占位符按下时会消失, 清空时则出现
textbox.KeyDown += textbox_KeyDown;
textbox.KeyUp += checkNull;
textbox.TextChanged += checkNull;
}
Label placeHolder = new Label();
placeHolder.AutoSize = true;
placeHolder.Enabled = false;
setName(placeHolder); //设置name属性
textbox.Parent.Controls.Add(placeHolder);
placeHolder.BackColor = textbox.BackColor;
relevanceDic.Add(textbox, placeHolder);
plhs.Add(placeHolder, new List<String>(languageTxt));
}
/// <summary>
/// //刷新并且开启占位符, 默认启用索引为0的那组占位符
/// </summary>
public static void Refresh()
{
Refresh(defaultIndex);
}
/// <summary>
/// //刷新并且开启占位符
/// </summary>
/// <param name="index">索引号,用于支持多语言,默认为0</param>
public static void Refresh(ushort index)
{
String content = String.Empty;
foreach (Control textBox in relevanceDic.Keys)
{
Label placeHolder = relevanceDic[textBox];
try
{
content = plhs[placeHolder][index]; //将关联内容设置为相应List的语言编号-1的值
}
catch
{
content = string.Empty;
}
setLocation(textBox, placeHolder); //设置占位符的位置
placeHolder.Text = content; //设置占位符的内容
//如果输入框不为空,则占位符不可见
if (!String.IsNullOrEmpty(textBox.Text)) {
placeHolder.Visible = false;
}
}
}
#endregion
#region 私有方法
/// <summary>
/// 检查是否为空,如果是则让占位符可见。事件,按键松开,以及文本改变时触发
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void checkNull(object sender, EventArgs e)
{
//若文本框为空,则将占位符设置为不可见
if ((sender as TextBox).Text.Trim().Equals(""))
{
relevanceDic[sender as Control].Visible = true;
}
}
/// <summary>
/// 按下按键时占位符不可见
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void textbox_KeyDown(object sender, KeyEventArgs e)
{
relevanceDic[sender as Control].Visible = false;
}
/// <summary>
/// 刷新位置
/// </summary>
private static void setLocation(Control textbox, Label placeHolder){
placeHolder.Location = new Point(textbox.Location.X + 4, textbox.Location.Y + (textbox.Height - 12) / 2); //字体为9像素时,标签高度为12 //可使用doeven先强制布局?
placeHolder.BringToFront();
}
/// <summary>
/// 设置占位符的名字
/// </summary>
/// <param name="placeHolder"></param>
private static void setName(Label placeHolder) {
nameNumber++;
placeHolder.Name = placeHolderName + nameNumber;
}
#endregion
}
//使用范例
//在form的load方法里调用
//Placeholder.setPlh(textBox1, "6至16位密码", "6-16 bit password", "6-16キャラクタ");
//Placeholder.refresh(0); //刷新并且开启占位符
}
这组代码支持多语言,可以为单个文本框设置多组占位符,然后调用Refresh(int index)来切换。
使用范例:
private void LoginForm_Load(object sender, EventArgs e)
{
Placeholder.setPlh(accountTxt, "邮箱/手机", "Email/Phone");
Placeholder.setPlh(passwordTxt, "6至16位密码", "6-16 bit password");
Placeholder.Refresh(); //刷新并且开启占位符
}