By default the items in the C# Combobox are left aligned. Are there any options available to change this justification apart from overriding DrawItem method and setting the combobox drawmode --> DrawMode.OwnerDrawFixed?
Cheers
By default the items in the C# Combobox are left aligned. Are there any options available to change this justification apart from overriding DrawItem method and setting the combobox drawmode --> DrawMode.OwnerDrawFixed?
Cheers
You could just set the control style to RightToLeft = RightToLeft.Yes
if you don't mind the drop widget on the other side as well.
or
set DrawMode = OwnerDrawFixed;
and hook the DrawItem
event,
then something like
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();
}
}
In WPF this would be as easy as specifying an ItemContainerStyle. In Windows Forms it's a little trickier. Without custom drawing, you could set the RightToLeft property on the ComboBox but this would unfortunately also affect the drop down button.
Since Windows Forms uses a native ComboBox, and Windows doesn't have a ComboBox style like ES_RIGHT that affects the text alignment, I think your only option is to resort to owner draw. It would probably be a good idea to derive a class from ComboBox and add a TextAlignment property or something. Then you would only apply your drawing if TextAlignment was centered or right aligned.
You must "DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed" and your own draw method like this.
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);
}
}
Unfortunately the approach with OwnDrawItem seems not to work if the combo box is set to DropDownList.Then one sees a white background instead of the expected gray. So I came with using a WPF combo box, with also does not look exactly as the "normal" combo box but is close enough.
For me it was sufficient to implement two properties, one method and one vent as follows:
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
}
© 2022 - 2024 — McMap. All rights reserved.