Posición desplegable de ComboBox

Tengo una forma maximizada que tiene control Combo-Box (atracado en la esquina superior derecha) con 500px de Width

Después de intentar abrir el cuadro combinado, la mitad de la lista sale de la pantalla. ¿Cómo puedo forzar que la lista se muestre dentro de la forma?

Problema complicado. No pude encontrar una buena solución para esto, simplemente una solución. Agregue una nueva clase y pegue el código que se muestra a continuación. Comstackr. Coloque el nuevo control desde la parte superior de la caja de herramientas en su formulario.

La solución no es muy buena. El problema es que la ventana desplegable ignorará el bash de moverlo hasta que se complete la animación desplegable. El efecto visual no es genial, verá la ventana desplegable y luego saltará hacia la izquierda. No conozco otra forma de darle una bofetada, tal vez alguien más lo haga.

Versión C #:

 using System; using System.Drawing; using System.Windows.Forms; using System.Runtime.InteropServices; public class MyComboBox : ComboBox { protected override void OnDropDown(EventArgs e) { // Is dropdown off the right side of the screen? Point pos = this.PointToScreen(this.Location); Screen scr = Screen.FromPoint(pos); if (scr.WorkingArea.Right < pos.X + this.DropDownWidth) { this.BeginInvoke(new Action(() => { // Retrieve handle to dropdown list COMBOBOXINFO info = new COMBOBOXINFO(); info.cbSize = Marshal.SizeOf(info); SendMessageCb(this.Handle, 0x164, IntPtr.Zero, out info); // Move the dropdown window RECT rc; GetWindowRect(info.hwndList, out rc); int x = scr.WorkingArea.Right - (rc.Right - rc.Left); SetWindowPos(info.hwndList, IntPtr.Zero, x, rc.Top, 0, 0, 5); })); } base.OnDropDown(e); } // P/Invoke declarations private struct COMBOBOXINFO { public Int32 cbSize; public RECT rcItem, rcButton; public int buttonState; public IntPtr hwndCombo, hwndEdit, hwndList; } private struct RECT { public int Left, Top, Right, Bottom; } [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")] private static extern bool SetWindowPos(IntPtr hWnd, IntPtr after, int x, int y, int cx, int cy, int flags); [DllImport("user32.dll")] private static extern bool GetWindowRect(IntPtr hWnd, out RECT rc); } 

Versión de VB.Net:

 Imports System Imports System.Drawing Imports System.Windows.Forms Imports System.Runtime.InteropServices Public Class MyComboBox Inherits ComboBox 'P/Invoke declarations Private Structure COMBOBOXINFO Public cbSize As Int32 Public rcItem As RECT Public rcButton As RECT Public buttonState As Integer Public hwndCombo As IntPtr Public hwndEdit As IntPtr Public hwndList As IntPtr End Structure Private Structure RECT Public Left As Integer Public Top As Integer Public Right As Integer Public Bottom As Integer End Structure  Private Shared Function SendMessageCb(hWnd As IntPtr, msg As Integer, wp As IntPtr, ByRef lp As COMBOBOXINFO) As IntPtr End Function  Private Shared Function SetWindowPos(hWnd As IntPtr, after As IntPtr, x As Integer, y As Integer, cx As Integer, cy As Integer, flags As Integer) As Boolean End Function  Private Shared Function GetWindowRect(hWnd As IntPtr, ByRef rc As RECT) As Boolean End Function Protected Overrides Sub OnDropDown(e As EventArgs) ' Is dropdown off the right side of the screen? Dim pos As Point = Me.PointToScreen(Me.Location) Dim scr As Screen = Screen.FromPoint(pos) If (scr.WorkingArea.Right < pos.X + Me.DropDownWidth) Then Me.BeginInvoke(New Action(Sub() 'Retrieve handle to dropdown list Dim info As COMBOBOXINFO = New COMBOBOXINFO() info.cbSize = Marshal.SizeOf(info) SendMessageCb(Me.Handle, &H164, IntPtr.Zero, info) 'Move the dropdown window Dim rc As RECT GetWindowRect(info.hwndList, rc) Dim x As Integer = scr.WorkingArea.Right - (rc.Right - rc.Left) SetWindowPos(info.hwndList, IntPtr.Zero, x, rc.Top, 0, 0, 5) End Sub)) End If MyBase.OnDropDown(e) End Sub End Class