

コンボボックスの選択中の項目について文字を右寄せに表示することは可能でしょうか。

TEXTboxではプロパティにTEXTAlighnがあるため設定できますがcomboboxにはないため設定ができず困っています


CC BY-SA 4.0
2020-04-21T14:47:15.473
65826
2023-11-01T07:05:00.657
2023-02-10T01:28:06.263
3060
39747
question
c#
C#のコンボボックスの表示時の文字を右寄せで表示したい


コメントに紹介した [Align Text in
Combobox](https://stackoverflow.com/q/11817062/9014308) の
[この回答](https://stackoverflow.com/a/58955315/9014308)
を参考に`ComboBox`に`TextAlign`プロパティを追加してみました。

元記事回答は以下のようにセンタリング固定でしたが、TextAlignプロパティ追加で変更が出来るようにしてあります。

> The post is a bit old but it may be still worth to say:  
>  both requirements are possible for Windows Forms ComboBox:
>
>   * Text align center (text area and the dropdown)
>     * For the text area, find the `Edit` control and set the `ES_CENTER`
> style for the control.
>     * For the dropdown items or the selected item in drop-down mode, to
> align text to center, just make the control owner-drawn and draw the text at
> center.
>   * Get rid of focus rectangle
>     * Make the control owner-drawn and just don't draw focus rectangle.
>

>
> 投稿は少し古いですが、それでも言う価値があるかもしれません：  
>  Windowsフォームコンボボックスでは、両方の要件が可能です。
>
>   * テキストの中央揃え（テキスト領域とドロップダウン）
>     * テキスト領域の場合は、`Edit`コントロールを見つけて、コントロールの`ES_CENTER`スタイルを設定します。
>     *
> ドロップダウンアイテムまたはドロップダウンモードで選択されたアイテムの場合、テキストを中央に揃えるには、コントロールをオーナー描画し、テキストを中央に描画します。
>   * フォーカス長方形を取り除く
>     * コントロールをオーナー描画にし、フォーカス長方形を描画しないようにします。
>

* * *

`ComboBoxAlign.Designer.cs`

[code]

    namespace ComboBoxAlign
    {
        partial class ComboBoxAlign
        {
            private System.ComponentModel.IContainer components = null;
            protected override void Dispose(bool disposing)
            {
                if (disposing && (components != null))
                {
                    components.Dispose();
                }
                base.Dispose(disposing);
            }
            private void InitializeComponent()
            {
                components = new System.ComponentModel.Container();
            }
        }
    }
    
[/code]

* * *

`ComboBoxAlign.cs`

[code]

    using System;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    namespace ComboBoxAlign
    {
        public partial class ComboBoxAlign : ComboBox
        {
            private HorizontalAlignment _TextAlign;
            public HorizontalAlignment TextAlign
            {
                get { return _TextAlign; }
                set { _TextAlign = value; SetupEdit(); }  // 直ぐに反映したいなら this.Refresh(); を追加
            }
            public ComboBoxAlign()
            {
                InitializeComponent();
                this.DrawMode = DrawMode.OwnerDrawFixed;
                _TextAlign = HorizontalAlignment.Left;
            }
            [DllImport("user32.dll")]
            private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
            [DllImport("user32.dll")]
            private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
            private const int GWL_STYLE = -16;
            private const int ES_MASK = -4;
            private const int ES_LEFT = 0x0000;
            private const int ES_CENTER = 0x0001;
            private 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 &= ES_MASK;
                int align = ES_LEFT;
                switch (_TextAlign)
                {
                    case HorizontalAlignment.Center: align = ES_CENTER; break;
                    case HorizontalAlignment.Right: align = ES_RIGHT; break;
                }
                style |= align;
                SetWindowLong(info.hwndEdit, GWL_STYLE, style);
            }
            protected override void OnDrawItem(DrawItemEventArgs e)
            {
                base.OnDrawItem(e);
                e.DrawBackground();
                var text = "";
                if (e.Index >= 0)
                {
                    text = GetItemText(Items[e.Index]);
                }
                TextFormatFlags flags = TextFormatFlags.Left;
                switch (this.TextAlign)
                {
                    case HorizontalAlignment.Center: flags = TextFormatFlags.HorizontalCenter; break;
                    case HorizontalAlignment.Right: flags = TextFormatFlags.Right; break;
                }
                TextRenderer.DrawText(e.Graphics, text, e.Font, e.Bounds, e.ForeColor, flags);
            }
        }
    }
    
[/code]


CC BY-SA 4.0
2020-04-27T17:02:36.823
66041
2020-04-27T17:02:36.823
26370
65826
answer