C# windows窗体如何在文本框的右侧或左侧添加图标
我正在构建一个Windows窗体应用程序,我有一个用于搜索的文本框 我想在文本框的右侧或左侧放置一个搜索图标 像这样: 我更喜欢右边的 更新1C# windows窗体如何在文本框的右侧或左侧添加图标,c#,.net,windows,windows-forms-designer,C#,.net,Windows,Windows Forms Designer,我正在构建一个Windows窗体应用程序,我有一个用于搜索的文本框 我想在文本框的右侧或左侧放置一个搜索图标 像这样: 我更喜欢右边的 更新1 我问的是Windows窗体,不是ASP.net或MVC,你可以创建一个新的UserControl来完成所需的工作。为此,您必须扩展TextBox类。请看下面的代码: public class IconTextBox : System.Windows.Forms.TextBox { public IconTextBox()
我问的是Windows窗体,不是ASP.net或MVC,你可以创建一个新的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方法中,可以指定图像。您还可以将其扩展为具有自定义属性,该属性可以是图像路径。你的选择 您可以使用
面板
、文本框
和图片框
文本框必须放在面板中,这样您就不能在搜索图片上写下内容。我建议使用
RichTextBox
而不是TextBox
。您可以在加载表单时设置:
public Form1()
{
InitializeComponent();
richTextBox1.BackgroundImage = Image.FromFile("image path");
}
您必须添加对事件的处理,如
TextChanged
和leave
,以显示和隐藏背景图像,就像Atanas的回答一样,我发现下面的方法很有效。可以设置SearchImage
和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; }
}
}
公共类搜索文本框:文本框
{
私有常量int EM_SETMARGINS=0xd3;
[System.Runtime.InteropServices.DllImport(“user32.dll”)]
专用静态外部IntPtr SendMessage(IntPtr hWnd、int msg、IntPtr wp、IntPtr lp);
私人PictureBox搜索PictureBox;
私人按钮取消搜索按钮;
公共搜索文本框()
{
cancelSearchButton=新建按钮();
cancelSearchButton.Anchor=AnchorStyles.Top | AnchorStyles.Right;
取消搜索按钮。大小=新大小(16,16);
cancelSearchButton.TabIndex=0;
cancelSearchButton.TabStop=false;
cancelSearchButton.FlatStyle=FlatStyle.Flat;
cancelSearchButton.FlatAppearance.BorderSize=0;
取消搜索按钮。Text=“”;
cancelSearchButton.Cursor=Cursors.Arrow;
控件。添加(取消搜索按钮);
取消搜索按钮。单击+=委派
{
Text=“”;
焦点();
};
searchPictureBox=新PictureBox();
searchPictureBox.Anchor=AnchorsStyles.Top | AnchorsStyles.Right;
searchPictureBox.Size=新的大小(16,16);
searchPictureBox.TabIndex=0;
searchPictureBox.TabStop=false;
控件。添加(searchPictureBox);
//发送EM_SETMARGINS以防止按钮下方的文本消失
发送消息(句柄,EM_设置边距,(IntPtr)2,(IntPtr)(16使用用户控件,或者每次需要添加代码时都添加代码可能会变得非常麻烦。我处理这个问题的方法是添加一个初始值设定项类,可以在运行时从我的表单中调用该类。此代码的行为是当用户开始键入时,图像消失。如果文本框没有内容,则显示图像。我处理e单击图片框的事件,将焦点设置为文本框,以保持它是控件一部分的错觉,并向左偏移,以允许显示|,显示文本框具有焦点并准备接收输入
通过编写控制器而不是用户控件,我可以避免通过我的用户控件传播文本框中的所有事件和属性。此类依赖于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);
}
}
}
只要文本框存在,并且已经添加到表单中,调用就可以随时发生。我正在尝试您的解决方案面板的目的是模拟“良好”文本框的属性。您还需要设置相应的属性以提供与文本框匹配的边框。并将文本框设置为无边框。更简单的是:使用标签!它可以显示图像,可以单击并为您保存一个昂贵的控件。您可以在加载事件中设置其父级:textBox1.parent=label1;textBox1.Location=Point.Empty;
若要在左侧显示图像,请为textbox.left!Meh.面板和标签选择合适的值。面板和标签并不比另一个贵。如果使用面板而不是标签,则更明显的是使用容器控件。奇怪的概念。从用户的角度来看,我更喜欢在右侧看到类似的图标控件的左侧,而不是示例中的左侧。@MPatel这是此网站中的搜索窗格:)请参见此处:这不是完全重复的,因为您询问的是图标而不是按钮。但答案几乎相同。只需稍加调整即可将按钮替换为PictureBox(或其他可以显示图标的内容)。我强烈推荐Hans的答案,而不是其他选项。我在哪里可以设置图像的路径?是什么阻止文本出现在图像上?@CodyGray在上面的示例中,图像路径在哪里?没有图像路径。您必须自己添加。Atanas的代码有一个BitmapImage
属性,该属性采用位图
>Bitmap
类有一个从文件加载位图的方法:Bitmap.FromFile(…)
多么糟糕的想法-问题是关于搜索文本框的问题\uu@TaW这个想法中最糟糕的是什么?你是说将文本框更改为richtextbox很糟糕,还是确切地说,请解释一个richtextbox
是一个非常昂贵的控件。这里不需要它的任何功能。即使使用PictureBox
也太过了。最简单的方法是在标签内使用文本框
@TaW,如果我发现您认为将“搜索”字作为默认文本放在文本框中比更改更好、更容易