/// <summary> /// This is used to select an item in the drop-down as the current item /// </summary> /// <param name="selIdx">The index of the selected item</param> internal void SelectItem(int selIdx) { dgDropDown.ClearSelection(); if (selIdx != -1) { DataGridHelper.ConcedeFocus(dgDropDown); dgDropDown.CurrentRowIndex = selIdx; dgDropDown.Select(selIdx); } }
/// <summary> /// This is used to set the default selected item, size and position the drop-down, and show it /// </summary> public void ShowDropDown() { int idx; if (!hasInitialized) { this.CreateHandle(); } idx = startIndex = owner.SelectedIndex; dgDropDown.ClearSelection(); dragOffset = Point.Empty; // Sometimes it shows the edit control so clear it DataGridHelper.ConcedeFocus(dgDropDown); if (idx != -1 && DataGridHelper.RowCount(dgDropDown) > idx) { dgDropDown.Select(idx); dgDropDown.CurrentRowIndex = idx; } // The owner positions us when using the simple style. There's also an odd sequence of events // related to updates to bound controls that can cause this control to get disposed after setting // the data grid's row index above so we'll stop in that case too. if (this.IsDisposed || owner.DropDownStyle == ComboBoxStyle.Simple) { return; } if (this.Width < owner.Width) { this.Width = owner.Width; } // Make sure we are within the screen bounds. Take into account the working area of all screens. // Note that in certain setups, the leftmost/uppermost screen(s) may have negative coordinates. Rectangle workingArea, screen = new Rectangle(); foreach (Screen s in Screen.AllScreens) { workingArea = s.WorkingArea; if (workingArea.X < screen.X) { screen.X = workingArea.X; } if (workingArea.Y < screen.Y) { screen.Y = workingArea.Y; } if (Math.Abs(workingArea.X) + workingArea.Width > screen.Width) { screen.Width = Math.Abs(workingArea.X) + workingArea.Width; } if (Math.Abs(workingArea.Y) + workingArea.Height > screen.Height) { screen.Height = Math.Abs(workingArea.Y) + workingArea.Height; } } Point pOwner = owner.Parent.PointToScreen(owner.Location); pOwner.Y += owner.Height; Point p = pOwner; if (this.Width > screen.Width) { this.Width = screen.Width; } if (this.Height > screen.Height) { this.Height = screen.Height; } if (p.X < screen.X) { p.X = screen.X; } if (p.Y < screen.Y) { p.Y = screen.Y; } if (p.X + this.Width > screen.X + screen.Width) { p.X = screen.X + screen.Width - this.Width - 1; } if (p.Y + this.Height > screen.Y + screen.Height) { p.Y = screen.Y + screen.Height - this.Height - 1; } // If we are covering the combo box, move the location above the combo box if (p.Y < pOwner.Y) { idx = pOwner.Y - this.Height - owner.Height; // If we would go off the top of the screen, figure out whether we would have more rows visible // if we moved the form above the combo box or left it where it is at below the combo box and // shrink it to fit. if (idx < screen.Y) { if (this.Height + idx > this.Height - (pOwner.Y - p.Y)) { this.Height += idx; idx = screen.Y; } else { this.Height -= (pOwner.Y - p.Y); idx = pOwner.Y; } } p.Y = idx; } this.Location = p; UnsafeNativeMethods.SetParent(this.Handle, IntPtr.Zero); this.Show(); // NOTE: We lose capture pretty quickly as the mouse isn't inside the drop-down. MouseLeave grabs it // for us again. this.Capture = true; }
/// <summary> /// Hide any edit control when the grid is scrolled /// </summary> /// <param name="sender">The sender of the event</param> /// <param name="e">The event arguments</param> private void DropDownDataGrid_Scroll(object sender, EventArgs e) { DataGridHelper.ConcedeFocus(this); }