 |
|
|
 |
|
 |
Thank you very much for your comment.
You are absolutely correct, the "DropDownClosed" event is not firing when the user clicks outside of the drop down. It does, however, fire when clicking the drop down arrow to close the popup. And it does fire when the popup is dynamically hidden.
I have made some changes to the control to fix this issue which I will upload to CodeProject soon. For the time being I have placed some instructions below. I think that this will address the problem that you mentioned above. Please make sure that you make a backup of your files prior to making the following changes:
#1 - Add the following code into the "PopupControl.cs" file:
public interface IPopupControlHost { #region Methods
/// <summary> /// Displays drop-down area of combo box, if not already shown. /// </summary> void ShowDropDown();
/// <summary> /// Hides drop-down area of combo box, if shown. /// </summary> void HideDropDown();
#endregion } #2 - Update them_dropDown_Closed function of the PopupControl class in the "PopupControl.xs" file to match the following:
private void m_dropDown_Closed(object sender, ToolStripDropDownClosedEventArgs e) { if (AutoResetWhenClosed) DisposeHost(); // Hide drop down within popup control. if (PopupControlHost != null) PopupControlHost.HideDropDown(); } #3 - Change the "CustomComboBox" class declaration in the "CustomComboBox.cs" file to the following:
public class CustomComboBox : ComboBox, IPopupControlHost Please let me know how you get on with this!
Many thanks, Lea Hayes
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I'm not a C# person and am getting a compile error on pt #2 of 3 above.
if (PopupControlHost != null) PopupControlHost.HideDropDown();
What is "PopupControlHost?"
I don't see it defined anywhere.
I look fwd to updated code being posted.
Thanks!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Ahh, sorry I forgot to mention, I have also added a new property to the "PopupControl" class in "PopupControl.cs".
Simply add the following directly beneath the "AutoResetWhenClosed" property (approx line 754):
/// <summary> /// Gets or sets the popup control host, this is used to hide/show popup. /// </summary> public IPopupControlHost PopupControlHost { get; set; } Give that a try and let me know if you have any more questions. Once you have confirmed that this fixes the problem that you were experiencing I will submit an update to CodeProject.
Thanks again, Lea Hayes
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Well that elliminated the compile error but the event was still not raised.
I'd be happy to debug this for you but I don't know C#!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Are you able to reproduce this problem with the example provided in the download on this article?
If so, could you please provide a detailed list of steps to reproduce?
i.e. The fix that I provided in the previous message solves the following problem on my system:
1. Click drop down arrow to open. 2. Click anywhere on form outside of drop down and drop down box. 3. Event is not raised (FIXED NOW)
1. Click drop down arrow to open. 2. Click drop down arrow to close. 3. Event is raised (NO CHANGES MADE)
Obviously this is an issue that I want to resolve.
Many thanks, Lea Hayes
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I followed your instruction from scratch 3 times and still DropDownClose event does not fire when focus is lost.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
 |
|
|
 |
|
|
 |
|
 |
Hi there,
First of all, i would like to say that i find this custom combobox really great and useful. But i think there's one thing it cannot do (or it seems really hard to do it). I'm trying to use this control to implement a real combobox using a listbox as the hosted control. What i want is to reutilize the size grip feature and, at the same time, maintain all the normal combobox functionality. So, in this scenario, hiding those "unwanted" properties will not help me at all. If i unhide them, the control might not be reusable in other scenarios. I'm also having trouble to mimic the combobox events - it doesn't fire when it is expected to.
My question is: is it possible to use your control in this scenario? Is there any other way where i can have a combobox dropdown with a size grip (using the DropdownList Style)? I know a normal combobox will only show a grip when using the AutoComplete feature, but i want to show the grip always.
Thanks in advanced.
You realize that everything you learn is in fact just learned, not necessarily true...
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi,
I am glad that you have found my combo box control useful!
One solution might be to create a new control with a name like "ListComboBox" which:
1. Constructs an instance of my combo box class, along with a list box. 2. Associates the list box with the combo box. 3. Provide access to the combo and list box properties that you need.
I have put together an example of how you might do this (see below). Simply put this in a file named "ListComboBox.cs". It works in much the same way as a regular list box, however it reacts more like a regular combo box. You will probably want to make some of your own alterations to this.
Thanks! Lea Hayes
using System; using System.ComponentModel; using System.Drawing; using System.Drawing.Design; using System.Windows.Forms;
namespace CustomComboDemo { public class ListComboBox : Control { #region Construction and destruction
public ListComboBox() { List = new ListBox(); Combo = new CustomComboBox.CustomComboBox(List); Combo.Dock = DockStyle.Fill; Controls.Add(Combo);
List.SelectedIndexChanged += new EventHandler(List_SelectedIndexChanged); Combo.TextChanged += new EventHandler(Combo_TextChanged); Combo.KeyDown += new KeyEventHandler(ListComboBox_KeyDown); }
#endregion
#region Events
void ListComboBox_KeyDown(object sender, KeyEventArgs e) { switch (e.KeyCode) { case Keys.Up: if (List.SelectedIndex > 0) --List.SelectedIndex; break; case Keys.Down: if (List.SelectedIndex + 1 < List.Items.Count) ++List.SelectedIndex; break; case Keys.Home: List.SelectedIndex = List.Items.Count > 0 ? 0 : -1; break; case Keys.End: List.SelectedIndex = List.Items.Count - 1; break; } }
void List_SelectedIndexChanged(object sender, EventArgs e) { // Adjust content of combo box text. Combo.Text = (List.SelectedItem != null) ? List.SelectedItem.ToString() : ""; Combo.HideDropDown(); Combo.Select(); }
void Combo_TextChanged(object sender, EventArgs e) { // Adjust selection within list control. List.SelectedIndex = List.FindStringExact(Combo.Text); }
#endregion
#region Combo Methods
public void ShowDropDown() { Combo.ShowDropDown(); }
public void HideDropDown() { Combo.HideDropDown(); }
#endregion
#region Combo Properties
[Browsable(false)] public bool IsDroppedDown { get { return Combo.IsDroppedDown; } }
[Category("Custom Drop-Down"), Description("Indicates if drop-down is resizable.")] public bool AllowResizeDropDown { get { return Combo.AllowResizeDropDown; } set { Combo.AllowResizeDropDown = value; } }
[Category("Custom Drop-Down"), Description("Indicates current sizing mode."), DefaultValue(CustomComboBox.CustomComboBox.SizeMode.UseComboSize)] public CustomComboBox.CustomComboBox.SizeMode DropDownSizeMode { get { return Combo.DropDownSizeMode; } set { Combo.DropDownSizeMode = value; } }
[Category("Custom Drop-Down")] public Size DropSize { get { return Combo.DropSize; } set { Combo.DropSize = value; } }
[Category("Custom Drop-Down"), Browsable(false)] public Size ControlSize { get { return Combo.ControlSize; } set { Combo.ControlSize = value; } }
#endregion
#region List Events
public event EventHandler DataSourceChanged { add { List.DataSourceChanged += value; } remove { List.DataSourceChanged -= value; } } public event EventHandler DisplayMemberChanged { add { List.DisplayMemberChanged += value; } remove { List.DisplayMemberChanged -= value; } } public event ListControlConvertEventHandler Format { add { List.Format += value; } remove { List.Format -= value; } }
[EditorBrowsable(EditorBrowsableState.Advanced)] [Browsable(false)] public event EventHandler FormatInfoChanged { add { List.FormatInfoChanged += value; } remove { List.FormatInfoChanged -= value; } } public event EventHandler FormatStringChanged { add { List.FormatStringChanged += value; } remove { List.FormatStringChanged -= value; } } public event EventHandler FormattingEnabledChanged { add { List.FormattingEnabledChanged += value; } remove { List.FormattingEnabledChanged -= value; } } public event EventHandler SelectedValueChanged { add { List.SelectedValueChanged += value; } remove { List.SelectedValueChanged -= value; } } public event EventHandler ValueMemberChanged { add { List.ValueMemberChanged += value; } remove { List.ValueMemberChanged -= value; } }
#endregion
#region List Methods
public string GetItemText(object item) { return List.GetItemText(item); }
public void ClearSelected() { List.ClearSelected(); }
public int FindString(string s) { return List.FindString(s); }
public int FindString(string s, int startIndex) { return List.FindString(s, startIndex); }
public int FindStringExact(string s) { return List.FindStringExact(s); }
public int FindStringExact(string s, int startIndex) { return FindStringExact(s, startIndex); }
public int GetItemHeight(int index) { return List.GetItemHeight(index); }
#endregion
#region List Properties
[AttributeProvider(typeof(IListSource))] [DefaultValue("")] [RefreshProperties(RefreshProperties.Repaint)] public object DataSource { get { return List.DataSource; } set { List.DataSource = value; } }
[TypeConverter("System.Windows.Forms.Design.DataMemberFieldConverter, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] [DefaultValue("")] [Editor("System.Windows.Forms.Design.DataMemberFieldEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] public string DisplayMember { get { return List.DisplayMember; } set { List.DisplayMember = value; } }
[EditorBrowsable(EditorBrowsableState.Advanced)] [Browsable(false)] [DefaultValue("")] public IFormatProvider FormatInfo { get { return List.FormatInfo; } set { List.FormatInfo = value; } }
[MergableProperty(false)] [Editor("System.Windows.Forms.Design.FormatStringEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] [DefaultValue("")] public string FormatString { get { return List.FormatString; } set { List.FormatString = value; } }
[DefaultValue(false)] public bool FormattingEnabled { get { return List.FormattingEnabled; } set { List.FormattingEnabled = value; } }
public int SelectedIndex { get { return List.SelectedIndex; } set { List.SelectedIndex = value; } }
[Browsable(false)] [DefaultValue("")] [Bindable(true)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public object SelectedValue { get { return List.SelectedValue; } set { List.SelectedValue = value; } }
[DefaultValue("")] [Editor("System.Windows.Forms.Design.DataMemberFieldEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] public string ValueMember { get { return List.ValueMember; } set { List.ValueMember = value; } }
[RefreshProperties(RefreshProperties.Repaint)] [DefaultValue(true)] [Localizable(true)] public bool IntegralHeight { get { return List.IntegralHeight; } set { List.IntegralHeight = value; } }
[Localizable(true)] [RefreshProperties(RefreshProperties.Repaint)] [DefaultValue(13)] public int ItemHeight { get { return List.ItemHeight; } set { List.ItemHeight = value; } }
[Editor("System.Windows.Forms.Design.ListControlStringCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] [Localizable(true)] [MergableProperty(false)] public ListBox.ObjectCollection Items { get { return List.Items; } }
[DefaultValue(false)] public bool MultiColumn { get { return List.MultiColumn; } set { List.MultiColumn = value; } }
[Localizable(true)] [DefaultValue(false)] public bool ScrollAlwaysVisible { get { return List.ScrollAlwaysVisible; } set { List.ScrollAlwaysVisible = value; } }
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [Browsable(false)] public ListBox.SelectedIndexCollection SelectedIndices { get { return List.SelectedIndices; } }
[Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [Bindable(true)] public object SelectedItem { get { return List.SelectedItem; } set { List.SelectedItem = value; } }
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [Browsable(false)] public ListBox.SelectedObjectCollection SelectedItems { get { return List.SelectedItems; } }
public virtual SelectionMode SelectionMode { get { return List.SelectionMode; } set { List.SelectionMode = value; } }
[DefaultValue(false)] public bool Sorted { get { return List.Sorted; } set { List.Sorted = value; } }
[Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public int TopIndex { get { return List.TopIndex; } set { List.TopIndex = value; } }
[Browsable(false)] [DefaultValue(false)] public bool UseCustomTabOffsets { get { return List.UseCustomTabOffsets; } set { List.UseCustomTabOffsets = value; } }
[DefaultValue(true)] public bool UseTabStops { get { return List.UseTabStops; } set { List.UseTabStops = value; } }
#endregion
#region Properties
protected CustomComboBox.CustomComboBox Combo { get; private set; } protected ListBox List { get; private set; }
#endregion } }
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi I am relatively new to this VS2005 and .Net winform development. Would you advice on how to add this control to my project for testing and possible customization please?!
TIA
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi,
Thanks for your interest!
To add this control to your project:
1. Select "Download source (Version 2.1) - 8.02 KB" from the top of this page. 2. Copy the files into your project directory. 3. Add all of these files into your C# project. 4. Rebuild your project from the "Build" menu. 5. Run your project, and then exit it. In some cases this eases the following step. 6. Drag and drop the control from the control box panel into your form. 7. You can then interact with your control by following the information in this article.
Many thanks, Lea Hayes
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi
I have done that but I get the following error
1. I tried to build the project again, then my vs2005 say there is missing directive or assembly reference in both "OldNewEvent.cs" and the "CustomComboBox.cs" files,
Here is what I found
- I open the source of CustomComboBox.cs then I found a type/namespace "ParentControlDesigner" is underlined (saying not found)
- then I open the source of OldNewEvent.cs and found a line "System.Linq" in the Declaration section is underlined (saying does not exists)
I am using .net 2.0 with vs2005 only.
Do I missed anything?
TIA
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi TIA,
> I open the source of CustomComboBox.cs then I found a type/namespace "ParentControlDesigner" is underlined (saying not found)
To solve this problem add the "System.Design" reference into your project.
> then I open the source of OldNewEvent.cs and found a line "System.Linq" in the Declaration section is underlined (saying does not exists)
In the "OldNewEvent.cs" file simply remove all of the using statements apart from "using System;" so that you have something which looks like the following. I think that I may have been using a later version of .NET when I made changes to the source files. "System.Linq" is not actually being used in this source, so it can just be removed.
using System;
namespace CustomComboBox { public class OldNewEventArgs : EventArgs { public OldNewEventArgs(T oldValue, T newValue) { OldValue = oldValue; NewValue = newValue; }
public T OldValue { get { return this.m_oldValue; } protected set { this.m_oldValue = value; } } public T NewValue { get { return this.m_newValue; } protected set { this.m_newValue = value; } }
T m_oldValue = default(T); T m_newValue = default(T); }
public delegate void OldNewEventHandler(object sender, OldNewEventArgs e); }
Give that a go and let me know how you get on.
Thanks, Lea Hayes
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I'm trying to set the datasource of the datagridview of combobox1 to a datatable, but it's not working. If I just add a datagridview to the form it works. But it doesn't work with the gridview in the combo box. Why is this?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi,
Yes this is an odd problem that you have discovered. However, I have two simple workarounds that you could use:
Workaround #1 Use the following code:
// Create grid view control. DataGridView gridView = new DataGridView(); gridView.BorderStyle = BorderStyle.None; gridView.AutoGenerateColumns = true; gridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; gridView.DataSource = this.peopleBindingSource1; gridView.Visible = false; // The following line is very important, the control is temporarily added to the form. Controls.Add(gridView); this.customComboBox1.DropDownControl = gridView;
Workaround #2 Add your data grid view to your form in the form designer, then simply reference it in the code:
this.customComboBox1.DropDownControl = this.dataGridView1;
Please let me know if this helps!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Thanks for the very nice work. Here are some changes that I made that you may want to consider.
1) I wanted to be able to hide the dropdown when the dropdowncontrol was hidden so in the PopupControl class in the InitializeHost method I hooked up to the controls.VisibleChanged method and when the control became non visible I called the Hide method on PopupControl.
2) The CustomComboBox class remembers the initial control size. This caused issues as I modified the size of the control (i.e. added items to my datagridview) after the control was initially visible. Then upon subsequent dropdowns the the dropdown was sized improperly. I added logic to always use the actual control size from within the AutoSizeDropDown.
Thanks again.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi,
Thank you for your kind words, and your two suggestions.
The second point that you mention was a design requirement for the project that I was working on at that point in time. However, I suspect that I could add a property to the control which allows the programmer to decide whether they want that functionality or not.
Thanks again! Lea Hayes
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
It's easier to just list the steps...
1. Click the down arrow of any of the controls in the demo 2. Enter some data on the dropped control 3. Press escape (The entered value doesn't show up -- Good) 4. Click the down arrow again 5. The previously entered data is still there (Not good. Most users expect the drop down and the displayed information to match)
I've been working on a similar issue at work, so that was the first thing I tested. The control looks GREAT! I'll probably base several of my existing controls on it. (Less support for me! )
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi,
I have checked what you are saying, but for me this was the intended functionality. If a value change is accepted within the drop-down then it is possible to reflect changes within the combo-box text area. Alternatively application specific code can be added to interact directly with the drop-down control.
If you wanted to adjust this functionality there are two ways that spring to mind:
1. Destroy and reconstruct the drop-down each time it is displayed (for some applications this may be too inefficient).
2. Add an interface which drop-down controls can optionally implement. If this interface is implemented then the drop-down control could have an oppertunity to reset itself upon drop-down (or other events).
public interface IDropDownControl { void ResetBeforeDropDown(); }
// This one DOES implement the drop-down control interface and so // will be reset to whatever state upon drop-down. public class MyControlA : UserControl, IDropDownControl { public ResetBeforeDropDown() { listBox1.SelectedIndex = -1; } }
// This one does NOT implement the drop-down control, but is STILL // compatible. public class MyControlB : UserControl { }
Then implement a class along the lines of:
public class MyCustomComboBox : CustomComboBox { protected override void ShowDropDown() { // If drop down control interface is implemented, invoke the // associated methods. IDropDownControl dropDownCtrl = DropDownControl as IDropDownControl; if (dropDownCtrl != null) dropDownCtrl.ResetBeforeDropDown();
// Show drop down like before. base.ShowDropDown(); } }
I hope that this is of help!
Lea Hayes
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hello I am a beginner in C # and would like a hint of how to customize the object appears in the dropdown window also a window into modal.
Tranks
Cristiano / Brazil
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi Cristiano!
When you say how to customize the object that appears in the dropdown window, are you referring to how to assign a drop-down control, or rather how to interact with a control which has already been assigned?
Please can you explain what you mean by display a window into modal? Do you want a dialog box to appear modally when you click the drop-down arrow instead of the dropdown? Or are you attempting to have a modal window appear when (for example) a button is pressed inside a dropdown control?
Thanks for taking interest in my control! I hope that it is of some use to you!
Lea Hayes
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |