【问题标题】:Align Text in Combobox在组合框中对齐文本
【发布时间】:2012-08-02 18:17:04
【问题描述】:

我想在组合框中对齐我的文本,以便它显示在组合框的中心告诉我如何执行此操作您还可以看到组合框周围有一个默认边框,当它处于焦点时如何删除那个边界也 请解决我的两个问题 谢谢

【问题讨论】:

  • 您不能在 Windows 窗体控件中专门执行此操作
  • 这两个要求都是可能的,使 TextAlign Center 成为编辑区域和下拉菜单。也摆脱了焦点矩形。我分享了一个answer

标签: c# winforms combobox visual-c#-express-2010


【解决方案1】:

本文对你有帮助:http://blog.michaelgillson.org/2010/05/18/left-right-center-where-do-you-align/

诀窍是将组合框的DrawMode-Property 设置为OwnerDrawFixed 并订阅其事件DrawItem

您的活动应包含以下代码:

// Allow Combo Box to center aligned
private void cbxDesign_DrawItem(object sender, DrawItemEventArgs e)
{
  // By using Sender, one method could handle multiple ComboBoxes
  ComboBox cbx = sender as ComboBox;
  if (cbx != null)
  {
    // Always draw the background
    e.DrawBackground();

    // Drawing one of the items?
    if (e.Index >= 0)
    {
      // Set the string alignment.  Choices are Center, Near and Far
      StringFormat sf = new StringFormat();
      sf.LineAlignment = StringAlignment.Center;
      sf.Alignment = StringAlignment.Center;

      // Set the Brush to ComboBox ForeColor to maintain any ComboBox color settings
      // Assumes Brush is solid
      Brush brush = new SolidBrush(cbx.ForeColor);

      // If drawing highlighted selection, change brush
      if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
        brush = SystemBrushes.HighlightText;

      // Draw the string
      e.Graphics.DrawString(cbx.Items[e.Index].ToString(), cbx.Font, brush, e.Bounds, sf);
    }
  }
}

要右对齐项目,您只需将StringAlignment.Center 替换为StringAlignment.Far

【讨论】:

  • 文章中的重要说明:要同时对齐选中的项目,您需要添加this.comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
  • 祝福你 modiX(和 OhBeWise)!
  • @Jack 因为提问者自 2012 年以来就没有在 Stack Overflow 上,而这个答案是在两年后添加的。
【解决方案2】:

ComboBox 不支持此功能。确切的原因已经在时间的迷雾中消失了,ComboBox 从九十年代初就已经存在,但肯定与让文本框部分中的文本与下拉列表中的文本对齐的尴尬有关。用 DrawItem 自定义绘图也无法解决,只会影响下拉项的外观。

作为一种可能的解决方法,您也许可以做一些奇怪的事情,比如用空格填充项目字符串,使它们看起来居中。您需要 TextRenderer.MeasureText() 来确定为每个项目添加多少空格。

您所说的“边框”不是边框,而是焦点矩形。您也无法摆脱这一点,Windows 拒绝让您创建一个不会显示具有焦点的控件的 UI。喜欢键盘而不是鼠标的用户会关心这一点。没有解决方法。

【讨论】:

  • 如果DropDownStyleDropDownList,即TextBox 不可编辑时,DrawItem 会影响已关闭ComboBox 的选定值的外观。
【解决方案3】:

RightToLeft 属性设置为true
它不会颠倒字符序列。它只是右对齐。

【讨论】:

  • 是的,虽然它也将下拉箭头移动到左侧。
  • 确实如此,但是滚动条向左移动,就像“从右到左”的手写一样。这不是一个好的解决方案。
【解决方案4】:

在自定义控件方面,Winforms 相当不灵活。如果您正在寻找更加自定义的用户体验,那么我建议您考虑创建一个 WPF 应用程序,该应用程序允许您定义自定义控件。不过,这需要一些工作,所以只有当你真的觉得有必要时,你才会想要去做。这是一个不错的网站,可以帮助您入门http://www.wpftutorial.net/

【讨论】:

  • 这就像在本田论坛上告诉本田车主他应该买一辆福特。原始问题询问有关 WinForms ComboBox 的问题。告诉他将整个应用程序转换为 WPF 是荒谬的。
  • @aaronburro 好吧,我的回答是五年前的事了,但我在一定程度上同意你的看法,如果我今天回复的话,我会将此作为评论。请记住,虽然不是每个人都在维护他们无法控制的遗留软件——许多开发人员使用 S.O.当他们发现新技术时。不要认为这对让人们了解他们可能没有探索过的替代技术有任何害处,并且可能会更好地满足他们的需求。
【解决方案5】:

帖子有点老了,但还是值得一说:

Windows 窗体组合框可以满足这两个要求:

  • 文本居中对齐(文本区域和下拉菜单)
    • 对于文本区域,找到Edit 控件并为该控件设置ES_CENTER 样式。
    • 对于下拉项或下拉模式中的选定项,要将文本居中对齐,只需将控件设为所有者绘制并在中心绘制文本即可。
  • 摆脱焦点矩形
    • 使控件由所有者绘制,而不是绘制焦点矩形。

示例

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public class MyComboBox : ComboBox
{
    public MyComboBox()
    {
        DrawMode = DrawMode.OwnerDrawFixed;
    }

    [DllImport("user32.dll")]
    static extern int GetWindowLong(IntPtr hWnd, int nIndex);
    [DllImport("user32.dll")]
    static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
    const int GWL_STYLE = -16;
    const int ES_LEFT = 0x0000;
    const int ES_CENTER = 0x0001;
    const int ES_RIGHT = 0x0002;
    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;
        public int Width { get { return Right - Left; } }
        public int Height { get { return Bottom - Top; } }
    }
    [DllImport("user32.dll")]
    public static extern bool GetComboBoxInfo(IntPtr hWnd, ref COMBOBOXINFO pcbi);

    [StructLayout(LayoutKind.Sequential)]
    public struct COMBOBOXINFO
    {
        public int cbSize;
        public RECT rcItem;
        public RECT rcButton;
        public int stateButton;
        public IntPtr hwndCombo;
        public IntPtr hwndEdit;
        public IntPtr hwndList;
    }
    protected override void OnHandleCreated(EventArgs e)
    {
        base.OnHandleCreated(e);
        SetupEdit();
    }
    private int buttonWidth = SystemInformation.HorizontalScrollBarArrowWidth;
    private void SetupEdit()
    {
        var info = new COMBOBOXINFO();
        info.cbSize = Marshal.SizeOf(info);
        GetComboBoxInfo(this.Handle, ref info);
        var style = GetWindowLong(info.hwndEdit, GWL_STYLE);
        style |= 1;
        SetWindowLong(info.hwndEdit, GWL_STYLE, style);
    }
    protected override void OnDrawItem(DrawItemEventArgs e)
    {
        base.OnDrawItem(e);
        e.DrawBackground();
        var txt = "";
        if (e.Index >= 0)
            txt = GetItemText(Items[e.Index]);
        TextRenderer.DrawText(e.Graphics, txt, Font, e.Bounds,
            ForeColor, TextFormatFlags.Left | TextFormatFlags.HorizontalCenter);
    }
}

【讨论】:

  • 我点赞了说这是不可能的帖子,所以我不得不点赞这篇帖子,说一旦我自己验证了这种方法是可行的。
  • 感谢@GrantJohnson 的反馈!
【解决方案6】:

您可以通过在查询中的显示成员之前添加空格来执行此类操作

例如:

combobox1.DataSource = Query(Select col1 , ('   '+col2) as Col2 from tableName) 
combobox1.DisplayMember = "Col2";
combobox1.ValueMember = "col1";

【讨论】:

    猜你喜欢
    • 2018-09-23
    • 1970-01-01
    • 1970-01-01
    • 2016-05-10
    • 1970-01-01
    • 1970-01-01
    • 2011-03-07
    • 1970-01-01
    • 2016-05-06
    相关资源
    最近更新 更多