/// <summary>
        /// Attach the helper to a combobox
        /// </summary>
        /// <param name="comboBox"></param>
        /// <param name="enableAutoCompleteOnEnter"></param>
        /// <param name="enableDeselectOnEsc"></param>
        /// <param name="enableShowListOnRightclick"></param>
        /// <param name="columnHeaders"></param>
        /// <param name="items"></param>
        /// <param name="viewMode"></param>
        /// <param name="postSetFunc"></param>
        public static void AttachComboBox(ComboBox comboBox, bool enableAutoCompleteOnEnter, bool enableDeselectOnEsc, bool enableShowListOnRightclick, bool enableTooltip, string[] columnHeaders, EnhancedComboBoxHelper.Items[] items, EnhancedComboBoxHelperList.ViewMode viewMode, Action postSetFunc)
        {
            CleanLists();

            if (comboBox == null)
                return;

            UpdateItems(comboBox, items, true);

            if (enableAutoCompleteOnEnter)
                SetAutoCompleteOnEnter(comboBox);

            if (enableDeselectOnEsc)
                SetDeselectOnEsc(comboBox);

            if (enableShowListOnRightclick && columnHeaders != null)
                SetShowListOnRightClick(comboBox, columnHeaders, viewMode, postSetFunc, true);

            if (enableTooltip)
                SetToolTipOnMouseOver(comboBox);
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="comboBox"></param>
        /// <param name="columnHeaders"></param>
        /// <param name="items"></param>
        /// <param name="selectedValue"></param>
        /// <param name="viewMode"></param>
        public EnhancedComboBoxHelperList(ComboBox comboBox, string[] columnHeaders, EnhancedComboBoxHelper.Items[] items, object selectedValue, ViewMode viewMode, Action postSetFunc)
        {
            InitializeComponent();

            this._columnHeaders = columnHeaders;
            this._items = items;
            this._selectedId = selectedValue;
            this._combobox = comboBox;
            this._viewMode = viewMode;
            this._postSetFunc = postSetFunc;

            //set title
            if (_viewMode == ViewMode.View)
                this.Text = "View";
            else
                this.Text = "Select";

            //set caller on change
            if (_viewMode == ViewMode.View)
            {
                checkBox_setcalleronchange.Checked = false;
                checkBox_setcalleronchange.Enabled = false;
            }
            else if (_viewMode == ViewMode.SelectOnChange)
            {
                checkBox_setcalleronchange.Checked = true;
            }
            else if (_viewMode == ViewMode.SelectOnDoubleClick)
            {
                checkBox_setcalleronchange.Checked = false;
            }

            //set change referred item mode
            _bindingSource.CurrentChanged += _bindingSource_CurrentChanged;

            //set type of select id
            if (items != null && _items.Count() > 0)
                this._typeofselectedId = items[0]._id.GetType();

            //check column headers consistency
            if (_items != null)
            {
                //get max values
                int maxvaluescount = 0;
                foreach (EnhancedComboBoxHelper.Items item in _items)
                {
                    if (item._values != null)
                    {
                        if (item._values.Count() > maxvaluescount)
                        {
                            maxvaluescount = item._values.Count();
                        }
                    }
                }
                //set columns header if null
                if (_columnHeaders == null || _columnHeaders.Length != maxvaluescount)
                {
                    _columnHeaders = new string[] { };
                    for (int i = 1; i <= maxvaluescount; i++)
                        _columnHeaders = _columnHeaders.Concat(new string[] { (i).ToString() }).ToArray();
                }
                //check duplicates
                Dictionary<string, int> columnHeadersCounts = new Dictionary<string, int>();
                foreach (string columnHeader in _columnHeaders)
                {
                    if (columnHeadersCounts.ContainsKey(columnHeader))
                        columnHeadersCounts[columnHeader]++;
                    else
                        columnHeadersCounts.Add(columnHeader, 1);
                }
                List<string> output = new List<string>();
                foreach (KeyValuePair<string, int> pair in columnHeadersCounts)
                {
                    if (pair.Value > 1)
                    {
                        for (int i = 1; i <= pair.Value; i++)
                            output.Add(pair.Key + "-" + i);
                    }
                    else
                        output.Add(pair.Key);
                }
                _columnHeaders = output.ToArray();
            }

            //set binding source
            advancedDataGridView_main.DataSource = _bindingSource;
        }
 /// <summary>
 /// Update items and set/update datasource
 /// </summary>
 /// <param name="comboBox"></param>
 /// <param name="items"></param>
 public static void UpdateItems(ComboBox comboBox, EnhancedComboBoxHelper.Items[] items)
 {
     UpdateItems(comboBox, items, true);
 }
        /// <summary>
        /// Show a tooltip
        /// </summary>
        /// <param name="comboBox"></param>
        /// <param name="items"></param>
        private static void ShowTooltip(ComboBox comboBox, EnhancedComboBoxHelper.Items[] items)
        {
            if (comboBox != null)
            {
                if (!String.IsNullOrEmpty(comboBox.Text))
                {
                    EnhancedComboBoxHelper.Items item = items.FirstOrDefault(r => r._value == comboBox.Text);
                    if (item != null)
                    {
                        if (item._values != null)
                        {
                            string tooltipText = "";
                            foreach (string value in item._values)
                                tooltipText += value + " ";

                            if (comboBox.Visible && tooltip.Tag == null)
                            {
                                if (!tooltipShown)
                                {
                                    tooltip.Show(tooltipText, comboBox, comboBox.Width / 2, comboBox.Height / 2);
                                    tooltip.Tag = comboBox;
                                    tooltipShown = true;
                                }
                                else
                                {
                                    tooltip.Hide(comboBox);
                                    tooltip.Tag = null;
                                    tooltipShown = false;
                                }
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Update items
        /// </summary>
        /// <param name="comboBox"></param>
        /// <param name="items"></param>
        /// <param name="updateDataSource"></param>
        public static void UpdateItems(ComboBox comboBox, EnhancedComboBoxHelper.Items[] items, bool updateDataSource)
        {
            if (!_attached_ComboBox.ContainsKey(comboBox))
                _attached_ComboBox.Add(comboBox, items);
            else
                _attached_ComboBox[comboBox] = items;

            if (!_attached_BindingSource.ContainsKey(comboBox))
            {
                BindingSource bindingSource = new BindingSource();
                bindingSource.DataSource = items;
                _attached_BindingSource.Add(comboBox, bindingSource);
            }
            else
            {
                if (new JavaScriptSerializer().Serialize(_attached_BindingSource[comboBox].DataSource) != new JavaScriptSerializer().Serialize(items))
                {
                    _attached_BindingSource[comboBox].DataSource = items;
                }
            }

            if (updateDataSource)
                UpdateDataSource(comboBox, items, true);
        }
        /// <summary>
        /// Set/Updat DataSource on combobox
        /// </summary>
        /// <param name="comboBox"></param>
        /// <param name="items"></param>
        /// <param name="resetSelectedIndex"></param>
        public static void UpdateDataSource(ComboBox comboBox, EnhancedComboBoxHelper.Items[] items, bool resetSelectedIndex)
        {
            if (comboBox == null)
                return;

            if (comboBox != null && items != null)
            {
                if (_attached_BindingSource.ContainsKey(comboBox))
                {
                    if (_attached_BindingSource[comboBox] != null)
                    {
                        if (comboBox.DataSource != _attached_BindingSource[comboBox])
                        {
                            comboBox.DataSource = _attached_BindingSource[comboBox];
                        }
                    }
                }
                if (comboBox.ValueMember != "_id")
                    comboBox.ValueMember = "_id";
                if (comboBox.DisplayMember != "_value")
                    comboBox.DisplayMember = "_value";
                if (resetSelectedIndex)
                    comboBox.SelectedIndex = -1;
            }
        }
 /// <summary>
 /// Attach the helper to a combobox, view mode set caller on change, autocomplete enabled, deselect enabled, showlist enabled, tooltip enabled
 /// </summary>
 /// <param name="comboBox"></param>
 /// <param name="columnHeaders"></param>
 /// <param name="items"></param>
 public static void AttachComboBox(ComboBox comboBox, string[] columnHeaders, EnhancedComboBoxHelper.Items[] items)
 {
     AttachComboBox(comboBox, true, true, true, true, columnHeaders, items, EnhancedComboBoxHelperList.ViewMode.SelectOnChange, null);
 }
 /// <summary>
 /// Attach the helper to a combobox, set the view mode, autocomplete enabled, deselect enabled, showlist enabled
 /// </summary>
 /// <param name="comboBox"></param>
 /// <param name="columnHeaders"></param>
 /// <param name="items"></param>
 /// <param name="viewMode"></param>
 /// <param name="postSetFunc"></param>
 public static void AttachComboBox(ComboBox comboBox, string[] columnHeaders, EnhancedComboBoxHelper.Items[] items, EnhancedComboBoxHelperList.ViewMode viewMode, Action postSetFunc)
 {
     AttachComboBox(comboBox, true, true, true, true, columnHeaders, items, viewMode, postSetFunc);
 }
 /// <summary>
 /// Attach the helper to a combobox, view mode set caller on change
 /// </summary>
 /// <param name="comboBox"></param>
 /// <param name="enableAutoCompleteOnEnter"></param>
 /// <param name="enableDeselectOnEsc"></param>
 /// <param name="enableShowListOnRightclick"></param>
 /// <param name="enableTooltip"></param>
 /// <param name="columnHeaders"></param>
 /// <param name="items"></param>
 public static void AttachComboBox(ComboBox comboBox, bool enableAutoCompleteOnEnter, bool enableDeselectOnEsc, bool enableShowListOnRightclick, bool enableTooltip, string[] columnHeaders, EnhancedComboBoxHelper.Items[] items)
 {
     AttachComboBox(comboBox, enableAutoCompleteOnEnter, enableDeselectOnEsc, enableShowListOnRightclick, enableTooltip, columnHeaders, items, EnhancedComboBoxHelperList.ViewMode.SelectOnChange, null);
 }