smart combobox control

This commit is contained in:
chudov
2010-03-22 06:34:27 +00:00
parent efc74b5adc
commit a08fbfe228
2 changed files with 177 additions and 135 deletions

View File

@@ -25,7 +25,7 @@ namespace BBBNOVA
private int _dropDownWidth = 0; private int _dropDownWidth = 0;
private int _maxDropDownItems = 8; private int _maxDropDownItems = 8;
private int _selectedIndex = -1; //private int _selectedIndex = -1;
private bool _isDroppedDown = false; private bool _isDroppedDown = false;
@@ -51,6 +51,9 @@ namespace BBBNOVA
[Category("Behavior"), Description("Occurs when the SelectedIndex property changes.")] [Category("Behavior"), Description("Occurs when the SelectedIndex property changes.")]
public event EventHandler SelectedIndexChanged; public event EventHandler SelectedIndexChanged;
//[Category("Behavior"), Description("Occurs when the SelectedValue property changes.")]
//public event EventHandler SelectedValueChanged;
[Category("Behavior"), Description("Occurs whenever a particular item/area needs to be painted.")] [Category("Behavior"), Description("Occurs whenever a particular item/area needs to be painted.")]
public event EventHandler<DrawItemEventArgs> DrawItem; public event EventHandler<DrawItemEventArgs> DrawItem;
@@ -189,55 +192,16 @@ namespace BBBNOVA
} }
} }
if (!value && _isDroppedDown) _dropDownClosedAt = DateTime.Now;
_isDroppedDown = value; _isDroppedDown = value;
if (_isDroppedDown) if (_isDroppedDown)
{ {
_controlHost.Control.Width = _dropDownWidth; _listBox.Width = _dropDownWidth;
_listBox.Height = CalculateListHeight();
_listBox.Refresh();
int borderHeight = _listBox.BorderStyle == BorderStyle.Fixed3D ? 10 : 3;
if (_listBox.Items.Count > 0)
{
int h = 0;
int i = 0;
int maxItemHeight = 0;
int highestItemHeight = 0;
foreach(object item in _listBox.Items)
{
int itHeight = _listBox.GetItemHeight(i);
if (highestItemHeight < itHeight)
{
highestItemHeight = itHeight;
}
h = h + itHeight;
if (i <= (_maxDropDownItems - 1))
{
maxItemHeight = h;
}
i = i + 1;
}
if (maxItemHeight > _dropDownHeight)
_listBox.Height = _dropDownHeight + borderHeight;
else
{
if (maxItemHeight > highestItemHeight )
_listBox.Height = maxItemHeight + borderHeight;
else
_listBox.Height = highestItemHeight + borderHeight;
}
}
else
{
_listBox.Height = 15 + borderHeight;
}
_popupControl.Show(this, CalculateDropPosition(), ToolStripDropDownDirection.BelowRight); _popupControl.Show(this, CalculateDropPosition(), ToolStripDropDownDirection.BelowRight);
} Capture = false;
_listBox.Capture = true;
}
Invalidate(); Invalidate();
if (_isDroppedDown) if (_isDroppedDown)
@@ -245,9 +209,11 @@ namespace BBBNOVA
} }
} }
[Category("Appearance"), Description("Selects the radius of combobox edges.")]
public BNRadius Radius public BNRadius Radius
{ {
get { return _radius; } get { return _radius; }
set { _radius = value; }
} }
[Category("Appearance"), Description("Selects the type of border around drop down list."), DefaultValue(BorderStyle.None)] [Category("Appearance"), Description("Selects the type of border around drop down list."), DefaultValue(BorderStyle.None)]
@@ -370,23 +336,27 @@ namespace BBBNOVA
_popupControl.Padding = new Padding(0); _popupControl.Padding = new Padding(0);
_popupControl.Margin = new Padding(0); _popupControl.Margin = new Padding(0);
_popupControl.AutoSize = true; _popupControl.AutoSize = true;
_popupControl.AutoClose = false;
_popupControl.DropShadowEnabled = true; _popupControl.DropShadowEnabled = true;
_popupControl.Items.Add(_controlHost); _popupControl.Items.Add(_controlHost);
_dropDownWidth = this.Width; _dropDownWidth = this.Width;
_listBox.SelectedValueChanged += new EventHandler(_listBox_SelectedValueChanged);
_listBox.SelectedIndexChanged += new EventHandler(_listBox_SelectedIndexChanged);
_listBox.MeasureItem += new MeasureItemEventHandler(_listBox_MeasureItem); _listBox.MeasureItem += new MeasureItemEventHandler(_listBox_MeasureItem);
_listBox.DrawItem += new DrawItemEventHandler(_listBox_DrawItem); _listBox.DrawItem += new DrawItemEventHandler(_listBox_DrawItem);
_listBox.MouseClick += new MouseEventHandler(_listBox_MouseClick); _listBox.MouseClick += new MouseEventHandler(_listBox_MouseClick);
_listBox.MouseUp += new MouseEventHandler(_listBox_MouseUp);
_listBox.MouseDown += new MouseEventHandler(_listBox_MouseDown);
_listBox.MouseMove += new MouseEventHandler(_listBox_MouseMove); _listBox.MouseMove += new MouseEventHandler(_listBox_MouseMove);
//(_listBox.DataManager as CurrencyManager).ListChanged += new ListChangedEventHandler(BNComboBox_ListChanged);
_popupControl.Closed += new ToolStripDropDownClosedEventHandler(_popupControl_Closed); _popupControl.Closed += new ToolStripDropDownClosedEventHandler(_popupControl_Closed);
_textBox.Resize += new EventHandler(_textBox_Resize); _textBox.Resize += new EventHandler(_textBox_Resize);
_textBox.TextChanged += new EventHandler(_textBox_TextChanged); _textBox.TextChanged += new EventHandler(_textBox_TextChanged);
} }
#endregion #endregion
@@ -395,16 +365,24 @@ namespace BBBNOVA
#region Overrides #region Overrides
protected override void OnCreateControl()
{
base.OnCreateControl();
_listBox.CreateControl();
_listBox.SelectedIndex = -1;
}
protected override void OnDataSourceChanged(EventArgs e) protected override void OnDataSourceChanged(EventArgs e)
{ {
this.SelectedIndex = 0; _listBox.SelectedIndex = -1;
base.OnDataSourceChanged(e); base.OnDataSourceChanged(e);
} }
protected override void OnDisplayMemberChanged(EventArgs e) protected override void OnDisplayMemberChanged(EventArgs e)
{ {
_listBox.DisplayMember = this.DisplayMember; _listBox.DisplayMember = this.DisplayMember;
this.SelectedIndex = this.SelectedIndex; _listBox.SelectedIndex = _listBox.SelectedIndex;
//this.SelectedIndex = this.SelectedIndex;
base.OnDisplayMemberChanged(e); base.OnDisplayMemberChanged(e);
} }
@@ -482,14 +460,15 @@ namespace BBBNOVA
base.OnMouseLeave(e); base.OnMouseLeave(e);
} }
private DateTime _dropDownClosedAt = DateTime.MinValue;
protected override void OnMouseDown(MouseEventArgs e) protected override void OnMouseDown(MouseEventArgs e)
{ {
//System.Diagnostics.Trace.WriteLine(string.Format("OnMouseDown({0})", SelectedIndex));
_textBox.Focus(); _textBox.Focus();
if (DateTime.Now - _dropDownClosedAt >= TimeSpan.FromSeconds(0.1)) if (e.Button == MouseButtons.Left)
if ((this.RectangleToScreen(rectBtn).Contains(MousePosition) || (DropDownStyle == ComboBoxStyle.DropDownList))) if ((this.RectangleToScreen(rectBtn).Contains(MousePosition) || (DropDownStyle == ComboBoxStyle.DropDownList)))
{
this.IsDroppedDown = !this.IsDroppedDown; this.IsDroppedDown = !this.IsDroppedDown;
}
base.OnMouseDown(e); base.OnMouseDown(e);
} }
@@ -501,13 +480,10 @@ namespace BBBNOVA
protected override void OnMouseWheel(MouseEventArgs e) protected override void OnMouseWheel(MouseEventArgs e)
{ {
if (e.Delta < 0) if (e.Delta < 0 && _listBox.SelectedIndex < _listBox.Items.Count - 1)
this.SelectedIndex = this.SelectedIndex + 1; _listBox.SelectedIndex = _listBox.SelectedIndex + 1;
else if (e.Delta > 0) else if (e.Delta > 0 && _listBox.SelectedIndex > 0)
{ _listBox.SelectedIndex = _listBox.SelectedIndex - 1;
if (this.SelectedIndex > 0)
this.SelectedIndex = this.SelectedIndex - 1;
}
base.OnMouseWheel(e); base.OnMouseWheel(e);
} }
@@ -518,18 +494,39 @@ namespace BBBNOVA
base.OnGotFocus(e); base.OnGotFocus(e);
} }
protected override void OnLostFocus(EventArgs e) protected override void OnLostFocus(EventArgs e)
{ {
if (!this.ContainsFocus) if (this.IsDroppedDown && !_popupControl.ContainsFocus && !this.ContainsFocus)
{ this.IsDroppedDown = false;
Invalidate();
}
base.OnLostFocus(e); base.OnLostFocus(e);
} }
private int _selectedIndex = -2;
protected override void OnSelectedValueChanged(EventArgs e)
{
//System.Diagnostics.Trace.WriteLine(string.Format("OnSelectedValueChanged({0}=>{1})", Text, _listBox.Text));
OnSelectedIndexChanged(e);
//this.SelectedIndex = _listBox.SelectedIndex;
//this.Invalidate(true);
Text = _listBox.SelectedValue != null ?
_listBox.GetItemText(_listBox.SelectedValue) :
"";
base.OnSelectedValueChanged(e);
}
protected override void OnSelectedIndexChanged(EventArgs e) protected override void OnSelectedIndexChanged(EventArgs e)
{ {
//System.Diagnostics.Trace.WriteLine(string.Format("OnSelectedIndexChanged({0}=>{1})", _selectedIndex, _listBox.SelectedIndex));
if (_selectedIndex == _listBox.SelectedIndex)
return;
_selectedIndex = _listBox.SelectedIndex;
if(SelectedIndexChanged!=null) if(SelectedIndexChanged!=null)
SelectedIndexChanged(this, e); SelectedIndexChanged(this, e);
@@ -539,7 +536,7 @@ namespace BBBNOVA
protected override void OnValueMemberChanged(EventArgs e) protected override void OnValueMemberChanged(EventArgs e)
{ {
_listBox.ValueMember = this.ValueMember; _listBox.ValueMember = this.ValueMember;
this.SelectedIndex = this.SelectedIndex; //_listBox.SelectedIndex = _listBox.SelectedIndex;
base.OnValueMemberChanged(e); base.OnValueMemberChanged(e);
} }
@@ -570,7 +567,7 @@ namespace BBBNOVA
{ {
_textBox.Text = value; _textBox.Text = value;
base.Text = _textBox.Text; base.Text = _textBox.Text;
Invalidate(); Invalidate(true);
OnTextChanged(EventArgs.Empty); OnTextChanged(EventArgs.Empty);
} }
} }
@@ -698,7 +695,7 @@ namespace BBBNOVA
} }
else else
{ {
ControlPaint.DrawStringDisabled(e.Graphics, _textBox.Text, Font, BackColor, rectText, sf); ControlPaint.DrawStringDisabled(e.Graphics, _textBox.Text, Font, Color1, rectText, sf);
} }
} }
/* /*
@@ -736,22 +733,14 @@ namespace BBBNOVA
public override int SelectedIndex public override int SelectedIndex
{ {
get { return _selectedIndex; } get { return _listBox.SelectedIndex; }
set set
{ {
if (_listBox == null ||
_listBox.Items.Count == 0 ||
_ignoreSelect ||
(this.DataSource != null && value < 0) ||
value < -1 ||
value > _listBox.Items.Count - 1
)
return;
_listBox.SelectedIndex = value; _listBox.SelectedIndex = value;
_selectedIndex = value;
Text = _listBox.GetItemText(_listBox.SelectedItem); //_selectedIndex = value;
OnSelectedIndexChanged(EventArgs.Empty); //if (this.DataSource == null || value >= 0)
//OnSelectedIndexChanged(EventArgs.Empty);
} }
} }
@@ -761,17 +750,17 @@ namespace BBBNOVA
set set
{ {
_listBox.SelectedItem = value; _listBox.SelectedItem = value;
this.SelectedIndex = _listBox.SelectedIndex; //this.SelectedIndex = _listBox.SelectedIndex;
} }
} }
public new object SelectedValue public new object SelectedValue
{ {
get { return base.SelectedValue; } get { return _listBox.SelectedValue; }
set set
{ {
base.SelectedValue = value; _listBox.SelectedValue = value;
} }
} }
protected override void RefreshItem(int index) protected override void RefreshItem(int index)
@@ -827,66 +816,74 @@ namespace BBBNOVA
} }
bool _ignoreSelect = false; private int _hoverItem = -1;
void _listBox_MouseMove(object sender, MouseEventArgs e) void _listBox_MouseMove(object sender, MouseEventArgs e)
{ {
int i; int i = _listBox.IndexFromPoint(e.Location);
for (i = 0; i < (_listBox.Items.Count); i++) if (_hoverItem != i)
{ {
if (_listBox.GetItemRectangle(i).Contains(_listBox.PointToClient(MousePosition))) _hoverItem = i;
{ _listBox.Invalidate();
_ignoreSelect = true; }
_listBox.SelectedIndex = i;
_ignoreSelect = false;
return;
}
}
} }
void _listBox_MouseClick(object sender, MouseEventArgs e) void _listBox_MouseDown(object sender, MouseEventArgs e)
{
int i = _listBox.IndexFromPoint(e.Location);
//System.Diagnostics.Trace.WriteLine(string.Format("_listBox_MouseDown({0})", i));
if (i >= 0)
_listBox.SelectedIndex = i;
IsDroppedDown = false;
}
void _listBox_MouseUp(object sender, MouseEventArgs e)
{
int i = _listBox.IndexFromPoint(e.Location);
//System.Diagnostics.Trace.WriteLine(string.Format("_listBox_MouseUp({0})", i));
if (i >= 0)
{
_listBox.SelectedIndex = i;
IsDroppedDown = false;
}
}
void _listBox_MouseClick(object sender, MouseEventArgs e)
{ {
if (_listBox.Items.Count == 0) int i = _listBox.IndexFromPoint(e.Location);
{ if (i >= 0)
return; {
} _listBox.SelectedIndex = i;
IsDroppedDown = false;
if (_listBox.SelectedItems.Count != 1) }
{
return;
}
this.SelectedIndex = _listBox.SelectedIndex;
if (DropDownStyle == ComboBoxStyle.DropDownList)
{
this.Invalidate(true);
}
IsDroppedDown = false;
} }
private int GetImageKey(int index) private int GetImageKey(int index)
{ {
if (this.ImageList == null) if (this.ImageList == null || index < 0)
return -1; return -1;
try object key = FilterItemOnProperty(_listBox.Items[index], ImageKeyMember ?? DisplayMember);
{ if (key == null)
object item = _listBox.Items[index]; return -1;
string key = (ImageKeyMember == null ? item : BindingContext[item, ImageKeyMember].Current) as string; if (key is int)
if (key == null) return (int)key;
return -1; if (key is string)
return this.ImageList.Images.IndexOfKey(key); return this.ImageList.Images.IndexOfKey(key as string);
}
catch { }
return -1; return -1;
} }
//void BNComboBox_ListChanged(object sender, ListChangedEventArgs e)
//{
// _listBox.Height = CalculateListHeight();
//}
void _listBox_DrawItem(object sender, DrawItemEventArgs e) void _listBox_DrawItem(object sender, DrawItemEventArgs e)
{ {
if (DrawMode == DrawMode.Normal) if (DrawMode == DrawMode.Normal)
{ {
e.DrawBackground(); Color fg = _hoverItem != -1 && _hoverItem == e.Index ? Color1 : Color4;
Color bg = _hoverItem != -1 && _hoverItem == e.Index ? Color4 : Color1;
e.Graphics.FillRectangle(new SolidBrush(bg), e.Bounds);
if (e.Index >= 0) if (e.Index >= 0)
{ {
@@ -909,7 +906,7 @@ namespace BBBNOVA
StringFormat sf = new StringFormat(StringFormatFlags.NoWrap); StringFormat sf = new StringFormat(StringFormatFlags.NoWrap);
sf.Alignment = StringAlignment.Near; sf.Alignment = StringAlignment.Near;
textBounds.Offset(-3, 0); textBounds.Offset(-3, 0);
e.Graphics.DrawString(_listBox.GetItemText(Items[e.Index]), e.Font, new SolidBrush(e.ForeColor), textBounds); e.Graphics.DrawString(_listBox.GetItemText(Items[e.Index]), e.Font, new SolidBrush(fg), textBounds);
} }
return; return;
} }
@@ -922,6 +919,16 @@ namespace BBBNOVA
} }
} }
void _listBox_SelectedIndexChanged(object sender, EventArgs e)
{
OnSelectedIndexChanged(e);
}
void _listBox_SelectedValueChanged(object sender, EventArgs e)
{
OnSelectedValueChanged(e);
}
void _listBox_MeasureItem(object sender, MeasureItemEventArgs e) void _listBox_MeasureItem(object sender, MeasureItemEventArgs e)
{ {
if (MeasureItem != null) if (MeasureItem != null)
@@ -933,12 +940,12 @@ namespace BBBNOVA
void _popupControl_Closed(object sender, ToolStripDropDownClosedEventArgs e) void _popupControl_Closed(object sender, ToolStripDropDownClosedEventArgs e)
{ {
if (_isDroppedDown) _dropDownClosedAt = DateTime.Now;
_isDroppedDown = false; _isDroppedDown = false;
if (!this.RectangleToScreen(this.ClientRectangle).Contains(MousePosition)) if (!this.RectangleToScreen(this.ClientRectangle).Contains(MousePosition))
{ {
hovered = false; hovered = false;
} }
_hoverItem = -1;
Invalidate(true); Invalidate(true);
} }
@@ -1000,6 +1007,39 @@ namespace BBBNOVA
Invalidate(true); Invalidate(true);
} }
private int CalculateListHeight()
{
int borderHeight = _listBox.BorderStyle == BorderStyle.None ? 3 : SystemInformation.BorderSize.Height * 4 + 3;
if (_listBox.Items.Count <= 0)
return 15 + borderHeight;
int h = 0;
int i = 0;
int maxItemHeight = 0;
int highestItemHeight = 0;
foreach (object item in _listBox.Items)
{
int itHeight = _listBox.GetItemHeight(i);
if (highestItemHeight < itHeight)
{
highestItemHeight = itHeight;
}
h = h + itHeight;
if (i <= (_maxDropDownItems - 1))
{
maxItemHeight = h;
}
i = i + 1;
}
if (maxItemHeight > _dropDownHeight)
return _dropDownHeight + borderHeight;
if (maxItemHeight > highestItemHeight)
return maxItemHeight + borderHeight;
return highestItemHeight + borderHeight;
}
private Point CalculateDropPosition() private Point CalculateDropPosition()
{ {
Point point = new Point(0, this.Height); Point point = new Point(0, this.Height);
@@ -1076,11 +1116,13 @@ namespace BBBNOVA
#endregion #endregion
} }
[Serializable]
public class BNRadius public class BNRadius
{ {
private int _topLeft = 0; private int _topLeft = 0;
public static readonly BNRadius Default = new BNRadius();
public int TopLeft public int TopLeft
{ {
get { return _topLeft; } get { return _topLeft; }

View File

@@ -154,7 +154,7 @@ namespace CUEControls
if (open) if (open)
flags |= GetInfoFlags.SHGFI_OPENICON; flags |= GetInfoFlags.SHGFI_OPENICON;
SHFILEINFO info = new SHFILEINFO(); SHFILEINFO info = new SHFILEINFO();
SHGetFileInfo(filename.FullName, (uint)filename.Attributes, ref info, (uint)Marshal.SizeOf(info), (uint)flags); SHGetFileInfo(filename.FullName, filename.Exists ? (uint)filename.Attributes : 0, ref info, (uint)Marshal.SizeOf(info), (uint)flags);
iIcon = MapIcon(info.hIcon, info.iIcon); iIcon = MapIcon(info.hIcon, info.iIcon);
DestroyIcon(info.hIcon); DestroyIcon(info.hIcon);
return iIcon; return iIcon;