组合框下拉位置 [英] ComboBox Dropdown Position

查看:199
本文介绍了组合框下拉位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有(停靠在右上角),其中有组合框控件的最大化形式500px的宽度

I have a maximized form which has Combo-Box control (docked in top-right) with 500px Width

试图打开组合框后,列表的一半进入外的屏幕。我怎么能强制列表显示表单中?

After trying to open the combo-box , the half of the list goes out-of-screen . how can I force list shows within form?

推荐答案

棘手的问题。我无法找到一个很好的修复,只是一个解决方法。添加一个新类并粘贴如下所示的code。编译。从工具箱的上方新的控制到您的表单。

Tricky problem. I could not find a good fix for this, merely a workaround. Add a new class and paste the code shown below. Compile. Drop the new control from the top of the toolbox onto your form.

解决方法是不是非常好。问题是,在下拉窗口将忽略移动它,直到下拉动画完成的尝试。视觉效果不是很大,你会看到窗口的下拉,然后跳转到左边。我不知道一个其他的方式来拍它的头,也许别人呢。

The workaround is not a very good one. The problem is that the dropdown window will ignore the attempt to move it until the drop-down animation is complete. The visual effect is not great, you'll see the window drop down, then jump to the left. I don't know an other way to slap it over the head, maybe somebody else does.

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

这篇关于组合框下拉位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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