我正在构建一个Windows表单应用程序,我有一个用于搜索目的的文本框。
我想在文本框右侧或左侧放置一个搜索图标
像这样:
我更喜欢正确的
我问的是Windows表单不是ASP.net或MVC
答案 0 :(得分:6)
您可以使用Panel
,TextBox
和PictureBox
。
TextBox必须放在面板中,这样您就无法在搜索图片上书写。
答案 1 :(得分:2)
您可以创建一个新的UserControl来完成所需的工作。您必须为此扩展TextBox类。请看下面的代码:
public class IconTextBox : System.Windows.Forms.TextBox
{
public IconTextBox() : base() { SetStyle(System.Windows.Forms.ControlStyles.UserPaint, true); this.Multiline = true; }
public System.Drawing.Bitmap BitmapImage
{
set;
get;
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
base.OnPaint(e);
System.Drawing.Image img = BitmapImage as System.Drawing.Image;
e.Graphics.DrawImage(img, new System.Drawing.Point(this.Width - (img.Width), 0));
}
}
在OnPaint方法中,您可以指定图像。您也可以将其扩展为具有可以作为图像路径的自定义属性。你的选择。
答案 2 :(得分:1)
按照Atanas的回答,我发现以下内容效果很好。可以设置CancelSearchImage
和public class SearchTextBox : TextBox
{
private const int EM_SETMARGINS = 0xd3;
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
private PictureBox searchPictureBox;
private Button cancelSearchButton;
public SearchTextBox()
{
cancelSearchButton = new Button();
cancelSearchButton.Anchor = AnchorStyles.Top | AnchorStyles.Right;
cancelSearchButton.Size = new Size(16, 16);
cancelSearchButton.TabIndex = 0;
cancelSearchButton.TabStop = false;
cancelSearchButton.FlatStyle = FlatStyle.Flat;
cancelSearchButton.FlatAppearance.BorderSize = 0;
cancelSearchButton.Text = "";
cancelSearchButton.Cursor = Cursors.Arrow;
Controls.Add(cancelSearchButton);
cancelSearchButton.Click += delegate
{
Text = "";
Focus();
};
searchPictureBox = new PictureBox();
searchPictureBox.Anchor = AnchorStyles.Top | AnchorStyles.Right;
searchPictureBox.Size = new Size(16, 16);
searchPictureBox.TabIndex = 0;
searchPictureBox.TabStop = false;
Controls.Add(searchPictureBox);
// Send EM_SETMARGINS to prevent text from disappearing underneath the button
SendMessage(Handle, EM_SETMARGINS, (IntPtr)2, (IntPtr)(16 << 16));
UpdateControlsVisibility();
}
protected override void OnTextChanged(EventArgs e)
{
base.OnTextChanged(e);
UpdateControlsVisibility();
}
private void UpdateControlsVisibility()
{
if (string.IsNullOrEmpty(Text))
{
cancelSearchButton.Visible = false;
searchPictureBox.Visible = true;
}
else
{
cancelSearchButton.Visible = true;
searchPictureBox.Visible = false;
}
}
[Browsable(true)]
public Image SearchImage
{
set
{
searchPictureBox.Image = value;
searchPictureBox.Left = Width - searchPictureBox.Size.Width - 4;
searchPictureBox.Top = Height - searchPictureBox.Size.Height - 4;
}
get { return searchPictureBox.Image; }
}
[Browsable(true)]
public Image CancelSearchImage
{
set
{
cancelSearchButton.Image = value;
cancelSearchButton.Left = Width - searchPictureBox.Size.Width - 4;
cancelSearchButton.Top = Height - searchPictureBox.Size.Height - 4;
}
get { return cancelSearchButton.Image; }
}
}
属性来控制使用的图像。
ProcessUser
答案 3 :(得分:1)
使用用户控件或每次要执行此操作时添加代码都会非常麻烦。我处理这个的方法是添加一个初始化类,可以在运行时从我的表单中调用它。此代码的行为是当用户开始键入时,图像消失。如果文本框没有内容,则显示图像。我处理图片框的click事件以将焦点设置到文本框以保留它是控件的一部分的错觉,并偏移左边以允许|显示文本框具有焦点并准备好接收输入。
通过编写控制器而不是用户控件,我可以避免通过用户控件从文本框传播所有事件和属性。此类依赖于System.Windows.Forms,可以直接包含在Windows窗体应用程序中,也可以添加到可以从多个应用程序调用的控件库中。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing;
namespace WindowsFormsApplication1
{
class TextBoxIcon
{
public static TextBoxIcon AddIcon(TextBox textbox, Image icon)
{
if (icon != null) {
return new TextBoxIcon(textbox, icon);
} else {
return null;
}
}
private TextBox _TextBox;
private PictureBox _PictureBox;
private TextBoxIcon(TextBox textbox, Image icon) {
this._TextBox = textbox;
this._PictureBox = new PictureBox();
this._PictureBox.BackColor = textbox.BackColor;
this._PictureBox.Image = ScaleImage(icon);
this._TextBox.Parent.Controls.Add(_PictureBox);
this._PictureBox.Location = new Point(textbox.Left + 5, textbox.Top + 2);
this._PictureBox.Size = new Size(textbox.Width - 10, textbox.Height - 4);
this._PictureBox.Anchor = textbox.Anchor;
this._PictureBox.Visible = _TextBox.Visible;
this._PictureBox.BringToFront();
textbox.Resize += TextBox_Resize;
textbox.TextChanged += TextBox_TextChanged;
textbox.Leave += TextBox_Leave;
_PictureBox.Click += PictureBox_Click;
textbox.VisibleChanged += TextBox_VisibleChanged;
}
public static Image ScaleImage(Image img) {
if (img.Height == 16) {
return img;
} else {
return new Bitmap(img, new Size((int)((img.Height / 16.0) * img.Width), 16));
}
}
private void TextBox_Resize(Object sender, EventArgs e) {
_PictureBox.Size = new Size(_TextBox.Width - 10, _TextBox.Height - 4);
}
private void TextBox_VisibleChanged(Object sender, EventArgs e) {
_PictureBox.Visible = _TextBox.Visible;
}
private void ShowPictureBox() {
_PictureBox.Visible = String.IsNullOrEmpty(_TextBox.Text);
}
private void TextBox_TextChanged(Object sender, EventArgs e) {
ShowPictureBox();
}
private void TextBox_Leave(Object sender, EventArgs e) {
ShowPictureBox();
}
public void PictureBox_Click(object sender, EventArgs e) {
_TextBox.Focus();
}
}
}
以下是从表单中使用类的方法:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
TextBoxIcon.AddIcon(txtSearch, Properties.Resources.search);
}
}
}
只要文本框存在且已添加到表单中,就可以随时进行调用。
答案 4 :(得分:0)
我建议使用RichTextBox
代替TextBox
。您可以在表单的加载中设置BackgroundImage property:
public Form1()
{
InitializeComponent();
richTextBox1.BackgroundImage = Image.FromFile("image path");
}
您必须添加TextChanged
和leave
等事件的处理才能显示和隐藏背景图片