我正在开发一个 C# WinForms 应用程序 (VS.NET 2008, .NET 3.5 sp 1)。在一个表单上,我有一个搜索字段,而不是在搜索字段旁边放置标签,我想在搜索字段本身的背景中显示一些灰色文字(例如“搜索术语”)。当用户开始在搜索字段中输入文本时,文字应该消失。我该如何实现这个效果?
我正在开发一个 C# WinForms 应用程序 (VS.NET 2008, .NET 3.5 sp 1)。在一个表单上,我有一个搜索字段,而不是在搜索字段旁边放置标签,我想在搜索字段本身的背景中显示一些灰色文字(例如“搜索术语”)。当用户开始在搜索字段中输入文本时,文字应该消失。我该如何实现这个效果?
您需要使用一些P/Invoke互操作代码来完成此操作。查找Win32 API SendMessage
函数和EM_SETCUEBANNER
消息。
最好发布代码而不是链接。我从这里发布此内容。
//Copyright (c) 2008 Jason Kemp
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Text;
public static class Win32Utility
{
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern Int32 SendMessage(IntPtr hWnd, int msg,
int wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam);
[DllImport("user32.dll")]
private static extern bool SendMessage(IntPtr hwnd, int msg, int wParam, StringBuilder lParam);
[DllImport("user32.dll")]
private static extern bool GetComboBoxInfo(IntPtr hwnd, ref COMBOBOXINFO pcbi);
[StructLayout(LayoutKind.Sequential)]
private struct COMBOBOXINFO
{
public int cbSize;
public RECT rcItem;
public RECT rcButton;
public IntPtr stateButton;
public IntPtr hwndCombo;
public IntPtr hwndItem;
public IntPtr hwndList;
}
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
private const int EM_SETCUEBANNER = 0x1501;
private const int EM_GETCUEBANNER = 0x1502;
public static void SetCueText(Control control, string text)
{
if (control is ComboBox)
{
COMBOBOXINFO info = GetComboBoxInfo(control);
SendMessage(info.hwndItem, EM_SETCUEBANNER, 0, text);
}
else
{
SendMessage(control.Handle, EM_SETCUEBANNER, 0, text);
}
}
private static COMBOBOXINFO GetComboBoxInfo(Control control)
{
COMBOBOXINFO info = new COMBOBOXINFO();
//a combobox is made up of three controls, a button, a list and textbox;
//we want the textbox
info.cbSize = Marshal.SizeOf(info);
GetComboBoxInfo(control.Handle, ref info);
return info;
}
public static string GetCueText(Control control)
{
StringBuilder builder = new StringBuilder();
if (control is ComboBox)
{
COMBOBOXINFO info = new COMBOBOXINFO();
//a combobox is made up of two controls, a list and textbox;
//we want the textbox
info.cbSize = Marshal.SizeOf(info);
GetComboBoxInfo(control.Handle, ref info);
SendMessage(info.hwndItem, EM_GETCUEBANNER, 0, builder);
}
else
{
SendMessage(control.Handle, EM_GETCUEBANNER, 0, builder);
}
return builder.ToString();
}
}
我认为通常做法是将文本的颜色设置为灰色,并填充提示文本。然后,编写文本字段焦点事件的处理程序,在获得和失去焦点时基于修改字段内容和颜色。以下是一些伪代码(抱歉,这完全不是C#代码。我现在在想Actionscript):
TextInput myInput;
boolean showingHint = true;
myInput.text = "Search Terms";
myInput.color = 0xcccccc;
myInput.onFocusGained = function() {
if(showingHint) {
myInput.text = "";
myInput.color = 0x000000;
showingHint = false;
}
}
myInput.onFocusLost = function() {
if(!showingHint && myInput.text.length == 0) {
myInput.text = "Search Terms";
myInput.color = 0xcccccc;
showingHint = true;
}
}