默认情况下,C#组合框中的项是左对齐的。除了重写DrawItem方法和设置组合框drawmode --> DrawMode.OwnerDrawFixed之外,是否还有其他选项可用于更改此对齐方式?欢呼
pbwdgjma1#
如果你不介意另一边的下拉控件,你可以把控件样式设置为RightToLeft = RightToLeft.Yes。或设置DrawMode = OwnerDrawFixed;并挂钩DrawItem事件,然后类似于
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(); } }
soat7uwm2#
在WPF中,这就像指定ItemContainerStyle一样简单。在Windows窗体中,这有点棘手。如果没有自定义绘图,您可以在ComboBox上设置RightToLeft属性,但不幸的是,这也会影响下拉按钮。由于Windows窗体使用本机ComboBox,而Windows没有像ES_RIGHT这样影响文本对齐的ComboBox样式,我认为您唯一的选择是诉诸所有者绘制。从ComboBox派生一个类并添加TextAlignment属性或其他东西可能是一个好主意。然后,只有在TextAlignment居中或右对齐时才应用绘图。
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); } }
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 }
4条答案
按热度按时间pbwdgjma1#
如果你不介意另一边的下拉控件,你可以把控件样式设置为
RightToLeft = RightToLeft.Yes
。或
设置
DrawMode = OwnerDrawFixed;
并挂钩DrawItem
事件,然后类似于soat7uwm2#
在WPF中,这就像指定ItemContainerStyle一样简单。在Windows窗体中,这有点棘手。如果没有自定义绘图,您可以在ComboBox上设置RightToLeft属性,但不幸的是,这也会影响下拉按钮。
由于Windows窗体使用本机ComboBox,而Windows没有像ES_RIGHT这样影响文本对齐的ComboBox样式,我认为您唯一的选择是诉诸所有者绘制。从ComboBox派生一个类并添加TextAlignment属性或其他东西可能是一个好主意。然后,只有在TextAlignment居中或右对齐时才应用绘图。
wmvff8tz3#
你必须“DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed”和你自己的绘制方法,就像这样。
4ngedf3f4#
不幸的是,如果组合框设置为DropDownList,OwnDrawItem的方法似乎不起作用。然后人们看到一个白色背景,而不是预期的灰色。所以我来使用WPF组合框,与也不完全看起来像“正常”组合框,但足够接近。
对我来说,实现两个属性就足够了,一个方法和一个vent如下: