Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# windows窗体如何在文本框的右侧或左侧添加图标_C#_.net_Windows_Windows Forms Designer - Fatal编程技术网

C# windows窗体如何在文本框的右侧或左侧添加图标

C# 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窗体应用程序,我有一个用于搜索的文本框

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

像这样:

我更喜欢右边的

更新1
我问的是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,如果我发现您认为将“搜索”字作为默认文本放在文本框中比更改更好、更容易