窗口形成如何将一个图标添加到文本框的右侧或左侧

我正在构build一个Windows窗体应用程序,我有一个用于search目的的文本框。

我想在文本框的右侧或左侧放置一个search图标

喜欢这个:

在这里输入图像说明

我宁愿在正确的

更新1

我问的不是ASP.net或MVC的Windows窗体

您可以使用PanelTextBoxPictureBox

在这里输入图像说明

TextBox必须放置在一个面板中,所以你不能在你的搜索图片上写字。

您可以创建一个新的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方法中,您可以指定图像。 你也可以扩展这个有一个自定义的属性,可以是图像路径。 你的选择。

每次使用用户控件或添加代码时,都会变得非常麻烦。 我处理这个的方式是添加一个初始化类,可以在运行时从我的表单调用。 这段代码的行为是当用户开始输入时,图像消失。 如果文本框没有内容,则显示图像。 我处理图片框的点击事件以将焦点设置到文本框以保留它是控件的一部分的错觉,并偏移左边以允许| 显示文本框具有焦点并准备好接收输入。

通过编写控制器而不是用户控件,我可以避免通过用户控件传播文本框中的所有事件和属性。 此类依赖于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); } } } 

只要文本框存在,并已被添加到表单中,该调用可以随时发生。

我建议使用RichTextBox而不是TextBox 。并且可以在窗体的Load中设置BackgroundImage属性 :

 public Form1() { InitializeComponent(); richTextBox1.BackgroundImage = Image.FromFile("image path"); } 

而且你必须添加像TextChanged这样的事件的处理,并leave来显示和隐藏背景图像

沿着阿塔纳斯的答案,我发现以下工作很好。

可以设置SearchImageCancelSearchImage属性来控制使用的图像。

发送EM_SETMARGINS消息以防止文本消失在按钮下面。


 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; } } } 

沿着阿塔纳斯的答案,我发现以下工作很好。 可以设置SearchImageCancelSearchImage属性来控制使用的图像。

 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; } } }