如何在组合框中的文本前添加空格 [英] How to add space before text in combobox

查看:83
本文介绍了如何在组合框中的文本前添加空格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我制作了自定义组合框,它有一个集成按钮来添加新项目,当DropDownStyle = ComboBoxStyle.DropDownList时效果很好但是当组合框DropDownStyle = ComboBoxStyle.DropDown组合框的文本覆盖按钮时出现问题我做了。如果组合框的DropDownStyle设置为DropDown,那么在文本之前是否有空格?你可以看到图片中的问题



http://i.stack.imgur.com/g5VZB.png [ ^ ]



  public   class  ComboBoxButton3:ComboBox 
{
public ComboBoxButton3()
{
myButton = new Button();

this .DrawMode = System.Windows.Forms.DrawMode.OwnerDrawVariable;
this .DropDownStyle = ComboBoxStyle.DropDownList;
}

受保护 覆盖 void OnCreateControl()
{
this .myButton.Size = 大小( 23 .ClientSize.Height);
this .myButton.Location = new Point( 0 0 );
this .myButton.Cursor = Cursors.Default;
this .Button.BackgroundImage = global :: app.Properties.Resources.add1;
this .Button.BackgroundImageLayout = ImageLayout.Stretch;
this .Button.FlatStyle = FlatStyle.Flat;
this .Controls.Add( this .myButton);

base .OnCreateControl();
}


受保护 覆盖 void OnDrawItem(DrawItemEventArgs e)
{
if this != null
{
e.DrawBackground();
if (e.Index > = 0
{
StringFormat sf = new StringFormat();
sf.LineAlignment = StringAlignment.Center;
sf.Alignment = StringAlignment.Center;

画笔画笔= SolidBrush( .ForeColor);

if ((e.State& DrawItemState.Selected)== DrawItemState.Selected)
brush = SystemBrushes.HighlightText;

e.Graphics.DrawString( this .Items [e.Index] .ToString(), .Font,brush,e.Bounds,sf);
}
}

base .OnDrawItem(e);
}

public 按钮myButton;
public 按钮按钮
{
获取
{
return myButton;
}
set
{
myButton = value ;
}
}
}





我尝试了什么:



i找到了相同问题的答案,但是要添加按钮到textBox,答案是在创建文本框时添加此代码,但它不适用于组合框



 受保护 覆盖  void  OnCreateControl()
{
// 发送EM_SETMARGINS以防止文本在按钮下方消失
SendMessage( this .Handle,0xd3,( IntPtr 2 ,( IntPtr )( this .mButton.Width<< 16 ));
base .OnCreateControl();
}
[System.Runtime.InteropServices.DllImport( user32.dll)]
private static extern IntPtr SendMessage( IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);

解决方案

注意:如何将空格字符(或任何其他字符串)添加到组合框项目的前(前缀)或结尾(后缀)的示例出现在最后,这里。



请理解,WinForms提供的这些基本控件基本上是小黑盒子,是基于旧COM控件的.NET的不透明包装。作为一个群体,他们是不一致的,我认为,除了极少数例外,任何时候开发人员使用Win API乱砍这些控件,都会浪费时间。



已经有一个有用的,经验证的方法(组合)来创建自定义控件:创建一个UserControl,其中包含您想要用作实体的原子控件。



因此,将UserControl添加到Project中,将ComboBox和Button添加到UserControl中。花些时间调整UserControl的视觉外观。



代码隐藏看起来很简单:

 使用系统; 
使用 System.Windows.Forms;

命名空间 YourNameSpace
{
public partial class UCComboBox:UserControl
{
public UCComboBox()
{
InitializeComponent();
}

// 新项目的事件处理程序按钮单击以注入 此处
public 操作< ComboBox> GetNewItemAction { set ; get ; }

// ComboBox选择的事件处理程序将在此处注入
public 操作< int,object> ComboSelectionAction { set ; get ; }

// 外部客户可以设置内容的一种可能方式(项目)
// 内部ComboBox,可选择清除
// 现有项目,或将新项目附加到现有项目
public void SetComboItems( bool doClearItemsFirst,< span class =code-keyword> params string [] items)
{
if (doClearItemsFirst)TheCombo.Items.Clear();

TheCombo.Items.AddRange(items);
}

// 点击按钮
private void btnAddNewItem_Click( object sender, EventArgs e)
{
if (GetNewItemAction!= null )GetNewItemAction(TheCombo );
}

// ComboBox中的选择
private void TheCombo_SelectedIndexChanged( object sender, EventArgs e)
{
if (ComboSelectionAction!= null )ComboSelectionAction(TheCombo) .SelectedIndex,TheCombo.SelectedItem);
}
}
}

使用此UserControl的一个示例:



a。假设您从ToolBox中拖放了一个UserControl实例,或者在代码中创建了一个实例:它名为'UCComboBox1:

  //  在表单中加载EventHandler: 
private void Form1_Load( object sender,EventArgs e)
{
UCComboBox1.SetComboItems(
true
one 两个 three four
five six seven 8 );

UCComboBox1.ComboSelectionAction = ComboSelectionAction;

UCComboBox1.GetNewItemAction = GetNewItemAction;
}

// 从UserControl ComboBox接收通知的事件
// 进行选择时
私有 void ComboSelectionAction( int ndx, object item)
{
Console.WriteLine( 所选索引: {0}所选项目:{1},ndx,item);
}

// 从UserControl按钮接收通知的事件
// 单击按钮时
private void GetNewItemAction(ComboBox comboBox)
{
comboBox.Items.Add( );
}

但是,你如何为ComboBox中的Items添加空格(或其他任何东西)?



嗯,您可以非常轻松地自动化:

  //  需要Linq  
// 在UserControl中
public void SetComboItems( bool doClearItemsFirst, string 前缀,字符串后缀,参数 string [] items)
{
if (doClearItemsFirst)TheCombo.Items.Clear();

TheCombo.Items.AddRange(AdjustItems(prefix,suffix,items));
}

public string [] AdjustItems(字符串前缀,字符串后缀,字符串 []项目)
{
return items.Select(itm = > 前缀+ itm +后缀).ToArray();
}

要使用此功能:

  //  在客户端 
UCComboBox1.SetComboItems(
true // 清除项目
{ // 前缀
} // 后缀
one 两个 三个 // < span class =code-comment> items
five 8);

注意:



0.万一你不清楚:'动作和'Func只是一种使用代表类型的便捷方式。这些工具在.NET 3.5中添加。



1.单击Button时将ComboBox本身的引用传递给外部客户端/用户的选择基于关于客户/用户可能希望对ComboBox项目进行一些编辑/调整而不仅仅是添加新项目的想法。如果只需要添加一个新的Item,你可以使用'Func返回一些'对象或'字符串添加到ComboBox,而不是'Action,并避免将ComboBox暴露在其宿主类之外。 BLOCKQUOTE>

i made custom combobox that have an integrated button to add new item and it works good in case when DropDownStyle = ComboBoxStyle.DropDownList but there is a problem when the combobox DropDownStyle = ComboBoxStyle.DropDown the text of the combobox is cover the button taht i made. is there away to make space before text in case whene the DropDownStyle for the combobox is set to DropDown ? you can see the problem in image

http://i.stack.imgur.com/g5VZB.png[^]

public class ComboBoxButton3 : ComboBox
{
    public ComboBoxButton3()
    {
        myButton = new Button();

        this.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawVariable;
        this.DropDownStyle = ComboBoxStyle.DropDownList;
    }

    protected override void OnCreateControl()
    {
        this.myButton.Size = new Size(23, this.ClientSize.Height);
        this.myButton.Location = new Point(0, 0);
        this.myButton.Cursor = Cursors.Default;
        this.Button.BackgroundImage = global::app.Properties.Resources.add1;
        this.Button.BackgroundImageLayout = ImageLayout.Stretch;
        this.Button.FlatStyle = FlatStyle.Flat;
        this.Controls.Add(this.myButton);

        base.OnCreateControl();
    }


    protected override void OnDrawItem(DrawItemEventArgs e)
    {
        if (this != null)
        {
            e.DrawBackground();
            if (e.Index >= 0)
            {
                StringFormat sf = new StringFormat();
                sf.LineAlignment = StringAlignment.Center;
                sf.Alignment = StringAlignment.Center;

                Brush brush = new SolidBrush(this.ForeColor);

                if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
                    brush = SystemBrushes.HighlightText;

                e.Graphics.DrawString(this.Items[e.Index].ToString(), this.Font, brush, e.Bounds, sf);
            }
        }

        base.OnDrawItem(e);
    }

    public Button myButton;
    public Button Button
    {
        get
        {
            return myButton;
        }
        set
        {
            myButton = value;
        }
    }
}



What I have tried:

i found an answer for same question but to add button to textBox and the answer was by adding this code when create textbox but it doesn't work for the combobox

protected override void OnCreateControl()
{
// Send EM_SETMARGINS to prevent text from disappearing underneath the button
SendMessage(this.Handle, 0xd3, (IntPtr)2, (IntPtr)(this.mButton.Width << 16));
base.OnCreateControl();
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);

解决方案

Note: an example of how to add a space character (or any other strings) to the front (prefix) or end (suffix) of the ComboBox Items appears at the end, here.

Please understand that these basic Controls provided by WinForms are essentially "little-black-boxes," an "opaque wrapper" of .NET around old COM based Controls. As a group, they are inconsistent, and I would argue that, with rare exceptions, any time a developer spends "hacking" these Controls using the Win API, is wasting time.

There is already a useful, proven, method ("Composition") to create custom Controls: make a UserControl that contains the "atomic" Controls you want to use as an "entity."

So, add a UserControl to your Project, put a ComboBox, and a Button, into the UserControl. Spend some time tweaking the visual appearance of the UserControl.

The code-behind can look this simple:

using System;
using System.Windows.Forms;

namespace YourNameSpace
{
    public partial class UCComboBox : UserControl
    {
        public UCComboBox()
        {
            InitializeComponent();
        }

        // event handler for new item Button click to be "injected" here
        public Action<ComboBox> GetNewItemAction { set; get; }

        // event handler for ComboBox selection to be "injected" here
        public Action<int, object> ComboSelectionAction { set; get; }

        // one possible way an external "client" can set the content (Items)
        // of the internal ComboBox, with an option to either clear
        // the existing Items, or append the new Items to the existing Items
        public void SetComboItems(bool doClearItemsFirst, params string[] items)
        {
            if(doClearItemsFirst) TheCombo.Items.Clear();

            TheCombo.Items.AddRange(items);
        }

        // the Button is clicked
        private void btnAddNewItem_Click(object sender, EventArgs e)
        {
            if (GetNewItemAction != null) GetNewItemAction(TheCombo);
        }

        // selection in the ComboBox
        private void TheCombo_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (ComboSelectionAction != null) ComboSelectionAction(TheCombo.SelectedIndex, TheCombo.SelectedItem);
        }
    }
}

An example of the use of this UserControl:

a. assuming you've either drag-dropped an instance of the UserControl from the ToolBox, or created one in code: it's named 'UCComboBox1:

// in Form Load EventHandler:
private void Form1_Load(object sender, EventArgs e)
{
    UCComboBox1.SetComboItems(
        true,
        "one", "two", "three", "four",
        "five", "six", "seven", "eight");
    
    UCComboBox1.ComboSelectionAction = ComboSelectionAction;
    
    UCComboBox1.GetNewItemAction = GetNewItemAction;
}

// event that receives notification from UserControl ComboBox
// when a selection is made
private void ComboSelectionAction(int ndx, object item)
{
    Console.WriteLine("selected index: {0} selected item: {1}", ndx, item);
}

// event that receives notification from UserControl Button
// when Button is clicked
private void GetNewItemAction(ComboBox comboBox)
{
    comboBox.Items.Add("nine");
}

But, how do you do add spaces (or anything else) to the Items in the ComboBox ?

Well, you could "automate" that pretty easily:

// requires Linq
// in the UserControl
public void SetComboItems(bool doClearItemsFirst, string prefix, string suffix, params string[] items)
{
    if(doClearItemsFirst) TheCombo.Items.Clear();

    TheCombo.Items.AddRange(AdjustItems(prefix, suffix, items));
}

public string[] AdjustItems(string prefix, string suffix, string[] items)
{
   return items.Select(itm => prefix + itm + suffix).ToArray();
}

To use this:

// in the client
UCComboBox1.SetComboItems(
    true,  // clear items
    "{",   // prefix
    "}",   // suffix
    "one", "two", "three", "four",   // items
    "five", "six", "seven", "eight");

Notes:

0. in case it's not clear to you: 'Action and 'Func are just a convenient way to use the Delegate Type. These facilities were added in .NET 3.5.

1. the choice to pass a reference to the ComboBox itself to the external client/user when the Button is clicked is based on the idea that the client/user may wish to do some editing/adjustment to the ComboBox Items beyond just adding a new Item. if adding a new Item is all that's required, you could use a 'Func that returned some 'object or 'string to add to the ComboBox, rather than an 'Action, and avoid "exposing" the ComboBox outside its host Class.


这篇关于如何在组合框中的文本前添加空格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆