2010-03-07 76 views
2

我已經擁有ComboBox控件最大化的形式(在右上方對接)與500像素Width組合框下拉位置

試圖打開組合框後,列表中的一半去失屏幕。我怎樣才能強制在表單內的列表顯示?

回答

7

棘手的問題。我無法找到一個很好的解決方法,只是一個解決方法。添加一個新的類並粘貼下面顯示的代碼。編譯。將新的控件從工具箱的頂部拖放到表單上。

解決方法不是一個很好的解決方法。問題是,下拉窗口將忽略嘗試移動它,直到下拉動畫完成。視覺效果不好,你會看到窗口下降,然後跳到左邊。我不知道用另一種方式把它拍在頭上,也許別人會這樣做。

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); 
} 

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 


    <DllImport("user32.dll", EntryPoint:="SendMessageW", CharSet:=CharSet.Unicode)> 
    Private Shared Function SendMessageCb(hWnd As IntPtr, msg As Integer, wp As IntPtr, ByRef lp As COMBOBOXINFO) As IntPtr 
    End Function 

    <DllImport("user32.dll")> 
    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 

    <DllImport("user32.dll")> 
    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 
+0

您的解決方案非常適用於我,我只是編輯它添加的一個Vb.Net版本源代碼。 - 馬克斯剛剛 – Max 2014-09-04 09:30:18