winforms C#中的右对齐组合框

kupeojn6  于 2023-10-23  发布在  C#
关注(0)|答案(4)|浏览(206)

默认情况下,C#组合框中的项是左对齐的。除了重写DrawItem方法和设置组合框drawmode --> DrawMode.OwnerDrawFixed之外,是否还有其他选项可用于更改此对齐方式?
欢呼

pbwdgjma

pbwdgjma1#

如果你不介意另一边的下拉控件,你可以把控件样式设置为RightToLeft = RightToLeft.Yes

设置DrawMode = OwnerDrawFixed;并挂钩DrawItem事件,然后类似于

private void comboBox1_DrawItem(object sender, DrawItemEventArgs e)
    {
        if (e.Index == -1)
            return;
        ComboBox combo = ((ComboBox) sender);
        using (SolidBrush brush = new SolidBrush(e.ForeColor))
        {
            e.DrawBackground();
            e.Graphics.DrawString(combo.Items[e.Index].ToString(), e.Font, brush, e.Bounds, new StringFormat(StringFormatFlags.DirectionRightToLeft));
            e.DrawFocusRectangle();
        }
    }
soat7uwm

soat7uwm2#

在WPF中,这就像指定ItemContainerStyle一样简单。在Windows窗体中,这有点棘手。如果没有自定义绘图,您可以在ComboBox上设置RightToLeft属性,但不幸的是,这也会影响下拉按钮。
由于Windows窗体使用本机ComboBox,而Windows没有像ES_RIGHT这样影响文本对齐的ComboBox样式,我认为您唯一的选择是诉诸所有者绘制。从ComboBox派生一个类并添加TextAlignment属性或其他东西可能是一个好主意。然后,只有在TextAlignment居中或右对齐时才应用绘图。

wmvff8tz

wmvff8tz3#

你必须“DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed”和你自己的绘制方法,就像这样。

protected virtual void OnDrawItem(object sender, DrawItemEventArgs e)
{
    var comboBox = sender as ComboBox;

    if (comboBox == null)
    {
        return;
    }

    e.DrawBackground();

    if (e.Index >= 0)
    {
        StringFormat sf = new StringFormat();
        sf.LineAlignment = StringAlignment.Center;
        sf.Alignment = StringAlignment.Center;

        Brush brush = new SolidBrush(comboBox.ForeColor);

        if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
        {
            brush = SystemBrushes.HighlightText;
        }

        e.Graphics.DrawString(comboBox.Items[e.Index].ToString(), comboBox.Font, brush, e.Bounds, sf);
    }
}
4ngedf3f

4ngedf3f4#

不幸的是,如果组合框设置为DropDownList,OwnDrawItem的方法似乎不起作用。然后人们看到一个白色背景,而不是预期的灰色。所以我来使用WPF组合框,与也不完全看起来像“正常”组合框,但足够接近。
对我来说,实现两个属性就足够了,一个方法和一个vent如下:

public partial class RightAlignedComboBox : ElementHost {

    public RightAlignedComboBox() {                   
        InitializeComponent();

        _comboBox = new() {
            HorizontalAlignment = HorizontalAlignment.Stretch,
            VerticalAlignment = VerticalAlignment.Stretch,
            HorizontalContentAlignment = HorizontalAlignment.Right,
            VerticalContentAlignment = VerticalAlignment.Center
        };

        _comboBox.SelectionChanged += comboBox_SelectionChanged;
        _comboBox.MouseWheel += comboBox_MouseWheel;

        this.Child = _comboBox;
    }

    #region Properties & Variables

    private ComboBox _comboBox;

    private IEnumerable<object> _items;

    /// <summary>
    /// Gets or sets the index specifying the currently selected item.
    /// </summary>      
    public int SelectedIndex {
        get {
            return _comboBox.SelectedIndex;
        }
        set {
            _comboBox.SelectedIndex = value;
        }
    }

    /// <summary>
    /// Gets or sets currently selected item in the combo box.
    /// </summary>      
    public object SelectedItem {
        get {
            return _items.ElementAt(_comboBox.SelectedIndex);
        }
        set {
            int selectedIndex = _items.IndexOfFirst(item => item.ToString() == value.ToString());
            _comboBox.SelectedIndex = selectedIndex;
        }
    }

    #endregion

    #region Methods

    /// <summary>
    /// Sets the items selectable in the combo box.
    /// </summary>
    /// <param name="items">The items to be put in the combo box.</param>
    public void SetItems(IEnumerable<object> items) {
        _items = items;

        _comboBox.Items.Clear();

        for (int i = 0; i < items.Count(); i++) {
            _comboBox.Items.Add(new ComboBoxItem() { Content = items.ElementAt(i).ToString() });
        }
    }

    #endregion

    #region Own events

    /// <summary>
    /// Event that is raised when the <see cref="SelectedIndex"/> changed either by clicking or by mouse wheel.
    /// </summary>
    public event EventHandler SelectionChangeCommitted = null;

    /// <summary>
    /// Raises the <see cref="SelectionChangeCommitted"/> event.
    /// </summary>
    private void onSelectionChangeCommitted() {
        SelectionChangeCommitted?.Invoke(this, EventArgs.Empty);
    }

    #endregion

    #region Events

    private void comboBox_MouseWheel(object sender, MouseWheelEventArgs e) {
        if (e.Delta < 0) {
            if (_comboBox.SelectedIndex != _comboBox.Items.Count - 1) {
                _comboBox.SelectedIndex++;
                onSelectionChangeCommitted();
            }
        }
        else {
            if (_comboBox.SelectedIndex != 0) {
                _comboBox.SelectedIndex--;
                onSelectionChangeCommitted();
            }
        }
    }

    private void comboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) {
        if (_comboBox.IsFocused) {
            onSelectionChangeCommitted();
        }
    }

    #endregion
}

相关问题