I want to show only the drop down list, not the text box portion of a combo box. How to do it?
Thanks in advance. | | newbieToVJS --Now C_ Saturday, August 25, 2007 5:29 AM | Add a new class to your project and paste the code shown below. Build. Drop the new control from the top of your toolbox onto the form. Add a button, double-click to get the event handler and write
comboDropdown1.DroppedDown = true;
The combobox is visible at design time but hidden at runtime. You'll want to position the control so its dropdown is in the correct position, it will show at the bottom of the control. Pretty neat, I think I'll have a use for it too.
using System; using System.Windows.Forms; using System.Runtime.InteropServices;
public class ComboDropdown : ComboBox { protected override void CreateHandle() { base.CreateHandle(); if (this.DesignMode) return; // Hide the combobox COMBOBOXINFO info = new COMBOBOXINFO(); info.cbSize = Marshal.SizeOf(info); SendMessageCb(this.Handle, 0x164, IntPtr.Zero, out info); uint flags = SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_HIDEWINDOW; SetWindowPos(info.hwndCombo, IntPtr.Zero, 0, 0, 0, 0, flags); }
// P/Invoke declarations private struct COMBOBOXINFO { public Int32 cbSize; public RECT rcItem; public RECT rcButton; public int buttonState; public IntPtr hwndCombo; public IntPtr hwndEdit; public IntPtr hwndList; } [StructLayout(LayoutKind.Sequential)] private struct RECT { public int Left; public int Top; public int Right; public int Bottom; } const UInt32 SWP_NOSIZE = 0x0001; const UInt32 SWP_NOMOVE = 0x0002; const UInt32 SWP_NOZORDER = 0x0004; const UInt32 SWP_NOREDRAW = 0x0008; const UInt32 SWP_NOACTIVATE = 0x0010; const UInt32 SWP_FRAMECHANGED = 0x0020; /* The frame changed: send WM_NCCALCSIZE */ const UInt32 SWP_SHOWWINDOW = 0x0040; const UInt32 SWP_HIDEWINDOW = 0x0080; const UInt32 SWP_NOCOPYBITS = 0x0100; const UInt32 SWP_NOOWNERZORDER = 0x0200; /* Don't do owner Z ordering */ const UInt32 SWP_NOSENDCHANGING = 0x0400; /* Don't send WM_WINDOWPOSCHANGING */
[DllImport("user32.dll", EntryPoint = "SendMessageW", CharSet = CharSet.Unicode)] private static extern IntPtr SendMessageCb(IntPtr hWnd, int msg, IntPtr wp, out COMBOBOXINFO lp); [DllImport("user32.dll")] static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); }
| | nobugz Saturday, August 25, 2007 3:35 PM | Add a new class to your project and paste the code shown below. Build. Drop the new control from the top of your toolbox onto the form. Add a button, double-click to get the event handler and write
comboDropdown1.DroppedDown = true;
The combobox is visible at design time but hidden at runtime. You'll want to position the control so its dropdown is in the correct position, it will show at the bottom of the control. Pretty neat, I think I'll have a use for it too.
using System; using System.Windows.Forms; using System.Runtime.InteropServices;
public class ComboDropdown : ComboBox { protected override void CreateHandle() { base.CreateHandle(); if (this.DesignMode) return; // Hide the combobox COMBOBOXINFO info = new COMBOBOXINFO(); info.cbSize = Marshal.SizeOf(info); SendMessageCb(this.Handle, 0x164, IntPtr.Zero, out info); uint flags = SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_HIDEWINDOW; SetWindowPos(info.hwndCombo, IntPtr.Zero, 0, 0, 0, 0, flags); }
// P/Invoke declarations private struct COMBOBOXINFO { public Int32 cbSize; public RECT rcItem; public RECT rcButton; public int buttonState; public IntPtr hwndCombo; public IntPtr hwndEdit; public IntPtr hwndList; } [StructLayout(LayoutKind.Sequential)] private struct RECT { public int Left; public int Top; public int Right; public int Bottom; } const UInt32 SWP_NOSIZE = 0x0001; const UInt32 SWP_NOMOVE = 0x0002; const UInt32 SWP_NOZORDER = 0x0004; const UInt32 SWP_NOREDRAW = 0x0008; const UInt32 SWP_NOACTIVATE = 0x0010; const UInt32 SWP_FRAMECHANGED = 0x0020; /* The frame changed: send WM_NCCALCSIZE */ const UInt32 SWP_SHOWWINDOW = 0x0040; const UInt32 SWP_HIDEWINDOW = 0x0080; const UInt32 SWP_NOCOPYBITS = 0x0100; const UInt32 SWP_NOOWNERZORDER = 0x0200; /* Don't do owner Z ordering */ const UInt32 SWP_NOSENDCHANGING = 0x0400; /* Don't send WM_WINDOWPOSCHANGING */
[DllImport("user32.dll", EntryPoint = "SendMessageW", CharSet = CharSet.Unicode)] private static extern IntPtr SendMessageCb(IntPtr hWnd, int msg, IntPtr wp, out COMBOBOXINFO lp); [DllImport("user32.dll")] static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); }
| | nobugz Saturday, August 25, 2007 3:35 PM | Tried this, butwhole combobox remained visible during runtime also.
Thanks, | | newbieToVJS --Now C_ Saturday, August 25, 2007 9:13 PM | Well, that's quite a disappointing outcome, it worked well when I tried it. Have you debugged it? Set a breakpoint in the CreateHandle() method and find out what is going wrong.
| | nobugz Saturday, August 25, 2007 9:18 PM | Thanks for your reply, but only code which seem to be working is:
comboDropdown1.DroppedDown = true;
I am now planning to use an extra panel to hide the textbox portion to make it appear like a "headless" combobox, which will be triggered by linkLabel1.DroppedDown=true.
| | newbieToVJS --Now C_ Sunday, August 26, 2007 2:12 AM | Hans:
I tried you code and it worked fine. At first I didn't have any Items so pressing the Button didn't do anything. With Items, pressing the Button toggled the dropdown. | | JohnWein Sunday, August 26, 2007 8:06 AM | The objective is to hide the texbox portion, not only toggling the dropdown. Did it hide the textbox? Which version are you using? Mine is Visual C# 2005 Express Edition. | | newbieToVJS --Now C_ Sunday, August 26, 2007 4:14 PM | Yes, it hides the textbox. Be sure to use the new custom control, not a regular ComboBox. It would work without problems in the Express edition too. | | nobugz Sunday, August 26, 2007 4:49 PM |
I tried again. But does not hide the "head".Here is the code.
Thanks
Code Snippet
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication1_testing
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
comboDropdown1.DroppedDown = true;
}
}
}
Code Snippet
namespace WindowsApplication1_testing
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.comboDropdown1 = new ComboDropdown();
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// comboDropdown1
//
this.comboDropdown1.FormattingEnabled = true;
this.comboDropdown1.Location = new System.Drawing.Point(50, 50);
this.comboDropdown1.Name = "comboDropdown1";
this.comboDropdown1.Size = new System.Drawing.Size(158, 21);
this.comboDropdown1.TabIndex = 0;
//
// button1
//
this.button1.Location = new System.Drawing.Point(27, 136);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(84, 32);
this.button1.TabIndex = 1;
this.button1.Text = "button1";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(292, 273);
this.Controls.Add(this.button1);
this.Controls.Add(this.comboDropdown1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
private ComboDropdown comboDropdown1;
private System.Windows.Forms.Button button1;
}
}
Code Snippet
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
public class ComboDropdown : ComboBox
{
protected override void CreateHandle()
{
base.CreateHandle();
if (this.DesignMode) return;
// Hide the combobox
COMBOBOXINFO info = new COMBOBOXINFO();
info.cbSize = Marshal.SizeOf(info);
SendMessageCb( this.Handle, 0x164, IntPtr.Zero, out info);
uint flags = SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_HIDEWINDOW;
SetWindowPos(info.hwndCombo, IntPtr.Zero, 0, 0, 0, 0, flags);
}
// P/Invoke declarations
private struct COMBOBOXINFO
{
public Int32 cbSize;
public RECT rcItem;
public RECT rcButton;
public int buttonState;
public IntPtr hwndCombo;
public IntPtr hwndEdit;
public IntPtr hwndList;
}
[ StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
const UInt32 SWP_NOSIZE = 0x0001;
const UInt32 SWP_NOMOVE = 0x0002;
const UInt32 SWP_NOZORDER = 0x0004;
const UInt32 SWP_NOREDRAW = 0x0008;
const UInt32 SWP_NOACTIVATE = 0x0010;
const UInt32 SWP_FRAMECHANGED = 0x0020; /* The frame changed: send WM_NCCALCSIZE */
const UInt32 SWP_SHOWWINDOW = 0x0040;
const UInt32 SWP_HIDEWINDOW = 0x0080;
const UInt32 SWP_NOCOPYBITS = 0x0100;
const UInt32 SWP_NOOWNERZORDER = 0x0200; /* Don't do owner Z ordering */
const UInt32 SWP_NOSENDCHANGING = 0x0400; /* Don't send WM_WINDOWPOSCHANGING */
[ DllImport("user32.dll", EntryPoint = "SendMessageW", CharSet = CharSet.Unicode)]
private static extern IntPtr SendMessageCb(IntPtr hWnd, int msg, IntPtr wp, out COMBOBOXINFO lp);
[ DllImport("user32.dll")]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
}
| | newbieToVJS --Now C_ Sunday, August 26, 2007 9:24 PM | I got it too work correctly as well, although I had to convert it to VB. He's the code with my other junk removed. I'm trying to make a auto-suggest DB driven control and the combo boxis not behaving the way I would like. This way I can use my own text box and keep the displayed text unaffected by the list and the selected item.
| PublicClasscntPartNumberCombo |
| InheritsComboBox |
|
| ProtectedOverridesSubCreateHandle() |
| MyBase.CreateHandle() |
|
| If(Me.DesignMode)ThenReturn |
| 'Hidethecombobox |
| DiminfoAsNewCOMBOBOXINFO |
| info.cbSize=Runtime.InteropServices.Marshal.SizeOf(info) |
| SendMessageCb(Me.Handle,&H164,IntPtr.Zero,info) |
| DimflagsAsUInteger=SWP_NOMOVEOrSWP_NOSIZEOrSWP_NOZORDEROrSWP_HIDEWINDOW |
| SetWindowPos(info.hwndCombo,IntPtr.Zero,0,0,0,0,flags) |
|
| EndSub |
|
| StructureCOMBOBOXINFO |
| DimcbSizeAsInt32 |
| DimrcitemAsRECT |
| DimrcButtonAsRECT |
| DimbuttonStateAsInteger |
| DimhwndComboAsIntPtr |
| DimhwndEditAsIntPtr |
| DimhwndListAsIntPtr |
| EndStructure |
|
|
| <Runtime.InteropServices.StructLayout(Runtime.InteropServices.LayoutKind.Sequential)>_ |
| StructureRECT |
| PublicLeftAsInt32 |
| PublicTopAsInt32 |
| PublicRightAsInt32 |
| PublicBottomAsInt32 |
| EndStructure |
|
| ConstSWP_NOSIZEAsUInt32=&H1 |
| ConstSWP_NOMOVEAsUInt32=&H2 |
| ConstSWP_NOZORDERAsUInt32=&H4 |
| ConstSWP_NOREDRAWAsUInt32=&H8 |
| ConstSWP_NOACTIVATEAsUInt32=&H10 |
| ConstSWP_FRAMECHANGEDAsUInt32=&H20'/*Theframechanged:sendWM_NCCALCSIZE*/ |
| ConstSWP_SHOWWINDOWAsUInt32=&H40 |
| ConstSWP_HIDEWINDOWAsUInt32=&H80 |
| ConstSWP_NOCOPYBITSAsUInt32=&H100 |
| ConstSWP_NOOWNERZORDERAsUInt32=&H200'/*Don'tdoownerZordering*/ |
| ConstSWP_NOSENDCHANGINGAsUInt32=&H400'/*Don'tsendWM_WINDOWPOSCHANGING*/ |
|
| PrivateDeclareUnicodeSubSendMessageCbLib"user32.dll"Alias"SendMessageW"(ByValhWndAsIntPtr,ByValmsgAsInteger,ByValwpAsIntPtr,ByReflpAsCOMBOBOXINFO) |
| DeclareSubSetWindowPosLib"user32.dll"(ByValhWndAsIntPtr,ByValhWndInsertAfterAsIntPtr,ByValxAsInteger,ByValyAsInteger,ByValcxAsInteger,ByValcyAsInteger,ByValuFlagsAsUInteger) |
|
| EndClass | | | Kratz Thursday, March 12, 2009 8:37 PM |
|