// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-// Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
+// Copyright (c) 2005-2008 Novell, Inc. (http://www.novell.com)
//
// Authors:
// Jonathan Chambers (jonathan.chambers@ansys.com)
+// Ivan N. Zlatev (contact@i-nz.net)
//
//
using System.Windows.Forms.Design;
namespace System.Windows.Forms.PropertyGridInternal {
- internal class PropertyGridView : System.Windows.Forms.ScrollableControl, IWindowsFormsEditorService {
+ internal class PropertyGridView : ScrollableControl, IWindowsFormsEditorService {
#region Private Members
- private double splitter_percent = .5;
private const int V_INDENT = 16;
- private int row_height;
- private int font_height_padding = 3;
+ private const int ENTRY_SPACING = 2;
private const int RESIZE_WIDTH = 3;
private const int BUTTON_WIDTH = 25;
+ private const int VALUE_PAINT_WIDTH = 19;
+ private const int VALUE_PAINT_INDENT = 27;
+ private double splitter_percent = .5;
+ private int row_height;
+ private int font_height_padding = 3;
private PropertyGridTextBox grid_textbox;
private PropertyGrid property_grid;
private bool resizing_grid;
- private int open_grid_item_count = -1;
- private int skipped_grid_items;
private PropertyGridDropDown dropdown_form;
private Form dialog_form;
private ImplicitVScrollBar vbar;
private StringFormat string_format;
private Font bold_font;
+ private Brush inactive_text_brush;
#endregion
#region Contructors
public PropertyGridView (PropertyGrid propertyGrid) {
property_grid = propertyGrid;
- property_grid.SelectedGridItemChanged+=new SelectedGridItemChangedEventHandler(HandleSelectedGridItemChanged);
- property_grid.PropertyValueChanged+=new PropertyValueChangedEventHandler(HandlePropertyValueChanged);
-
- string_format = new StringFormat();
+ string_format = new StringFormat ();
string_format.FormatFlags = StringFormatFlags.NoWrap;
string_format.Trimming = StringTrimming.None;
- grid_textbox = new PropertyGridTextBox();
- grid_textbox.DropDownButtonClicked +=new EventHandler(DropDownButtonClicked);
- grid_textbox.DialogButtonClicked +=new EventHandler(DialogButtonClicked);
+ grid_textbox = new PropertyGridTextBox ();
+ grid_textbox.DropDownButtonClicked +=new EventHandler (DropDownButtonClicked);
+ grid_textbox.DialogButtonClicked +=new EventHandler (DialogButtonClicked);
-
- dropdown_form = new PropertyGridDropDown();
+ dropdown_form = new PropertyGridDropDown ();
dropdown_form.FormBorderStyle = FormBorderStyle.None;
dropdown_form.StartPosition = FormStartPosition.Manual;
dropdown_form.ShowInTaskbar = false;
dialog_form.FormBorderStyle = FormBorderStyle.None;
dialog_form.ShowInTaskbar = false;
- skipped_grid_items = 0;
row_height = Font.Height + font_height_padding;
grid_textbox.Visible = false;
grid_textbox.Font = this.Font;
- grid_textbox.BackColor = this.BackColor;
+ grid_textbox.BackColor = SystemColors.Window;
// Not working at all, used to??
- grid_textbox.Validating += new CancelEventHandler(TextBoxValidating);
- grid_textbox.ToggleValue+=new EventHandler(grid_textbox_ToggleValue);
- this.Controls.Add(grid_textbox);
+ // grid_textbox.Validating += new CancelEventHandler (TextBoxValidating);
+ grid_textbox.ToggleValue+=new EventHandler (grid_textbox_ToggleValue);
+ this.Controls.Add (grid_textbox);
- vbar = new ImplicitVScrollBar();
+ vbar = new ImplicitVScrollBar ();
vbar.Visible = false;
- vbar.ValueChanged+=new EventHandler(HandleValueChanged);
+ vbar.Value = 0;
+ vbar.ValueChanged+=new EventHandler (VScrollBar_HandleValueChanged);
vbar.Dock = DockStyle.Right;
- this.Controls.AddImplicit(vbar);
+ this.Controls.AddImplicit (vbar);
resizing_grid = false;
- bold_font = new Font(this.Font, FontStyle.Bold);
+ bold_font = new Font (this.Font, FontStyle.Bold);
+ inactive_text_brush = new SolidBrush (ThemeEngine.Current.ColorGrayText);
- ForeColorChanged+=new EventHandler(RedrawEvent);
- BackColorChanged+=new System.EventHandler(RedrawEvent);
- FontChanged+=new EventHandler(RedrawEvent);
- SizeChanged+=new EventHandler(RedrawEvent);
+ ForeColorChanged+=new EventHandler (RedrawEvent);
+ BackColorChanged+=new System.EventHandler (RedrawEvent);
+ FontChanged+=new EventHandler (RedrawEvent);
- SetStyle(ControlStyles.DoubleBuffer, true);
- SetStyle(ControlStyles.UserPaint, true);
- SetStyle(ControlStyles.AllPaintingInWmPaint, true);
- SetStyle(ControlStyles.ResizeRedraw, false);
+ SetStyle (ControlStyles.Selectable, true);
+ SetStyle (ControlStyles.DoubleBuffer, true);
+ SetStyle (ControlStyles.UserPaint, true);
+ SetStyle (ControlStyles.AllPaintingInWmPaint, true);
+ SetStyle (ControlStyles.ResizeRedraw, true);
}
#endregion
#region Protected Instance Methods
- protected override void OnFontChanged(EventArgs e) {
- bold_font = new Font(this.Font, FontStyle.Bold);
+ protected override void OnFontChanged (EventArgs e) {
+ base.OnFontChanged (e);
-
+ bold_font = new Font (this.Font, FontStyle.Bold);
row_height = Font.Height + font_height_padding;
- base.OnFontChanged (e);
}
- protected override void OnDoubleClick(EventArgs e) {
- if (property_grid.SelectedGridItem.Expandable)
- property_grid.SelectedGridItem.Expanded = !property_grid.SelectedGridItem.Expanded;
- else
- ToggleValue();
- Invalidate();
- base.OnDoubleClick (e);
+ private void InvalidateItemLabel (GridEntry item)
+ {
+ Invalidate (new Rectangle (0, ((GridEntry)item).Top, SplitterLocation, row_height));
+ }
+
+ private void InvalidateItem (GridEntry item)
+ {
+ if (item == null)
+ return;
+
+ Rectangle rect = new Rectangle (0, item.Top, Width, row_height);
+ Invalidate (rect);
+
+ if (item.Expanded) {
+ rect = new Rectangle (0, item.Top + row_height, Width,
+ Height - (item.Top + row_height));
+ Invalidate (rect);
+ }
}
- protected override void OnPaint(PaintEventArgs e) {
- // Decide if we need a scrollbar
- open_grid_item_count = 0;
+ protected override void OnDoubleClick (EventArgs e)
+ {
+ if (property_grid.SelectedGridItem != null && property_grid.SelectedGridItem.Expandable)
+ property_grid.SelectedGridItem.Expanded = !property_grid.SelectedGridItem.Expanded;
+ else
+ ToggleValue ((GridEntry)property_grid.SelectedGridItem);
+ }
+ protected override void OnPaint (PaintEventArgs e)
+ {
// Background
e.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (BackColor), ClientRectangle);
- // Left column
- e.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (property_grid.LineColor), 0,0,V_INDENT, ClientRectangle.Height);
-
-
int yLoc = -vbar.Value*row_height;
- DrawGridItems(property_grid.grid_items, e, 1, ref yLoc);
+ if (property_grid.RootGridItem != null)
+ DrawGridItems (property_grid.RootGridItem.GridItems, e, 1, ref yLoc);
- // Grid
- DrawGrid(e);
-
- UpdateScrollBar();
-
- base.OnPaint(e);
+ UpdateScrollBar ();
}
- protected override void OnMouseWheel(MouseEventArgs e) {
- if (vbar == null || !vbar.Visible) {
+ protected override void OnMouseWheel (MouseEventArgs e)
+ {
+ if (vbar == null || !vbar.Visible)
return;
- }
-
- if (e.Delta < 0) {
- vbar.Value = Math.Min(vbar.Value + SystemInformation.MouseWheelScrollLines, vbar.Maximum);
- } else {
- vbar.Value = Math.Max(0, vbar.Value - SystemInformation.MouseWheelScrollLines);
- }
+ if (e.Delta < 0)
+ vbar.Value = Math.Min (vbar.Value + SystemInformation.MouseWheelScrollLines, vbar.Maximum - vbar.SmallChange);
+ else
+ vbar.Value = Math.Max (0, vbar.Value - SystemInformation.MouseWheelScrollLines);
base.OnMouseWheel (e);
}
protected override void OnMouseMove (MouseEventArgs e) {
+ if (property_grid.RootGridItem == null)
+ return;
if (resizing_grid) {
- int loc = Math.Max(e.X,2*V_INDENT);
+ int loc = Math.Max (e.X,2*V_INDENT);
SplitterPercent = 1.0*loc/Width;
- Refresh();
}
if (e.X > SplitterLocation - RESIZE_WIDTH && e.X < SplitterLocation + RESIZE_WIDTH)
this.Cursor = Cursors.SizeWE;
base.OnMouseMove (e);
}
- protected override void OnMouseDown (MouseEventArgs e) {
+ protected override void OnMouseDown (MouseEventArgs e)
+ {
+ base.OnMouseDown (e);
+ if (property_grid.RootGridItem == null)
+ return;
+
+ if (!TrySetEntry ((GridEntry)property_grid.SelectedGridItem, grid_textbox.Text)) {
+ FocusSelection ();
+ return;
+ }
+
if (e.X > SplitterLocation - RESIZE_WIDTH && e.X < SplitterLocation + RESIZE_WIDTH) {
resizing_grid = true;
}
else {
int offset = -vbar.Value*row_height;
- GridItem foundItem = GetSelectedGridItem(property_grid.grid_items, e.Y, ref offset);
-
+ GridItem foundItem = GetSelectedGridItem (property_grid.RootGridItem.GridItems, e.Y, ref offset);
+
if (foundItem != null) {
- if (foundItem.Expandable) {
- if (e.X >=3 && e.X <= 11 && (e.Y % row_height >= row_height/2-2 && e.Y % row_height <= row_height/2+4)) {
- foundItem.Expanded = !foundItem.Expanded;
- Invalidate();
- }
- }
+ if (foundItem.Expandable && ((GridEntry)foundItem).PlusMinusBounds.Contains (e.X, e.Y))
+ foundItem.Expanded = !foundItem.Expanded;
+
this.property_grid.SelectedGridItem = foundItem;
+ if (!GridLabelHitTest (e.X)) {
+ // send mouse down so we get the carret under cursor
+ grid_textbox.SendMouseDown (PointToScreen (e.Location));
+ }
}
-
- base.OnMouseDown (e);
}
}
base.OnMouseUp (e);
}
- protected override void OnKeyPress(KeyPressEventArgs e) {
- if (property_grid.SelectedGridItem.Expandable)
- property_grid.SelectedGridItem.Expanded = !property_grid.SelectedGridItem.Expanded;
- base.OnKeyPress (e);
+ protected override void OnResize (EventArgs e) {
+ base.OnResize (e);
+ if (property_grid.SelectedGridItem != null) { // initialized already
+ UpdateView ();
+ // MS scrolls to the currently selected item on resize, even
+ // when it's not in the visible area.
+ //
+ ScrollToItem ((GridEntry)property_grid.SelectedGridItem);
+ }
+ }
+
+ private void UnfocusSelection ()
+ {
+ Select (this);
+ }
+
+ private void FocusSelection ()
+ {
+ Select (grid_textbox);
+ }
+
+ protected override bool ProcessDialogKey (Keys keyData) {
+ GridEntry selectedItem = (GridEntry) property_grid.SelectedGridItem;
+ if (selectedItem != null
+ && grid_textbox.Visible) {
+ switch (keyData) {
+ case Keys.Enter:
+ if (TrySetEntry (selectedItem, grid_textbox.Text))
+ UnfocusSelection ();
+ return true;
+ case Keys.Escape:
+ if (selectedItem.IsEditable)
+ UpdateItem (selectedItem); // reset value
+ UnfocusSelection ();
+ return true;
+ case Keys.Tab:
+ FocusSelection ();
+ return true;
+ default:
+ return false;
+ }
+ }
+ return base.ProcessDialogKey (keyData);
+ }
+
+ private bool TrySetEntry (GridEntry entry, object value)
+ {
+ if (entry == null || grid_textbox.Text.Equals (entry.ValueText))
+ return true;
+
+ if (entry.IsEditable || !entry.IsEditable && (entry.HasCustomEditor || entry.AcceptedValues != null) ||
+ !entry.IsMerged || entry.HasMergedValue ||
+ (!entry.HasMergedValue && grid_textbox.Text != String.Empty)) {
+ string error = null;
+ bool changed = entry.SetValue (value, out error);
+ if (!changed && error != null) {
+ if (property_grid.ShowError (error, MessageBoxButtons.OKCancel) == DialogResult.Cancel)
+ UpdateItem (entry); // restore value, repaint, etc
+ else
+ return false;
+ }
+ }
+ return true;
+ }
+
+ protected override bool IsInputKey (Keys keyData) {
+ switch (keyData) {
+ case Keys.Left:
+ case Keys.Right:
+ case Keys.Enter:
+ case Keys.Escape:
+ case Keys.Up:
+ case Keys.Down:
+ case Keys.PageDown:
+ case Keys.PageUp:
+ case Keys.Home:
+ case Keys.End:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ private GridEntry MoveUpFromItem (GridEntry item, int up_count)
+ {
+ GridItemCollection items;
+ int index;
+
+ /* move back up the visible rows (and up the hierarchy as necessary) until
+ up_count == 0, or we reach the top of the display */
+ while (up_count > 0) {
+ items = item.Parent != null ? item.Parent.GridItems : property_grid.RootGridItem.GridItems;
+ index = items.IndexOf (item);
+
+ if (index == 0) {
+ if (item.Parent.GridItemType == GridItemType.Root) // we're at the top row
+ return item;
+ item = (GridEntry)item.Parent;
+ up_count --;
+ }
+ else {
+ GridEntry prev_item = (GridEntry)items[index-1];
+ if (prev_item.Expandable && prev_item.Expanded) {
+ item = (GridEntry)prev_item.GridItems[prev_item.GridItems.Count - 1];
+ }
+ else {
+ item = prev_item;
+ }
+ up_count --;
+ }
+ }
+ return item;
+ }
+
+ private GridEntry MoveDownFromItem (GridEntry item, int down_count)
+ {
+ while (down_count > 0) {
+ /* if we're a parent node and we're expanded, move to our first child */
+ if (item.Expandable && item.Expanded) {
+ item = (GridEntry)item.GridItems[0];
+ down_count--;
+ }
+ else {
+ GridItem searchItem = item;
+ GridItemCollection searchItems = searchItem.Parent.GridItems;
+ int searchIndex = searchItems.IndexOf (searchItem);
+
+ while (searchIndex == searchItems.Count - 1) {
+ searchItem = searchItem.Parent;
+
+ if (searchItem == null || searchItem.Parent == null)
+ break;
+
+ searchItems = searchItem.Parent.GridItems;
+ searchIndex = searchItems.IndexOf (searchItem);
+ }
+
+ if (searchIndex == searchItems.Count - 1) {
+ /* if we got all the way back to the root with no nodes after
+ us, the original item was the last one */
+ return item;
+ }
+ else {
+ item = (GridEntry)searchItems[searchIndex+1];
+ down_count--;
+ }
+ }
+ }
+
+ return item;
+ }
+
+ protected override void OnKeyDown (KeyEventArgs e)
+ {
+ GridEntry selectedItem = (GridEntry)property_grid.SelectedGridItem;
+
+ if (selectedItem == null) {
+ /* XXX not sure what MS does, but at least we shouldn't crash */
+ base.OnKeyDown (e);
+ return;
+ }
+
+ if (!TrySetEntry (selectedItem, grid_textbox.Text)) {
+ FocusSelection ();
+ return;
+ }
+
+ switch (e.KeyData & Keys.KeyCode) {
+ case Keys.Left:
+ if (e.Control) {
+ if (SplitterLocation > 2 * V_INDENT)
+ SplitterPercent -= 0.01;
+
+ e.Handled = true;
+ break;
+ }
+ else {
+ /* if the node is expandable and is expanded, collapse it.
+ otherwise, act just like the user pressed up */
+ if (selectedItem.Expandable && selectedItem.Expanded) {
+ selectedItem.Expanded = false;
+ e.Handled = true;
+ break;
+ }
+ else
+ goto case Keys.Up;
+ }
+ case Keys.Right:
+ if (e.Control) {
+ if (SplitterLocation < Width)
+ SplitterPercent += 0.01;
+
+ e.Handled = true;
+ break;
+ }
+ else {
+ /* if the node is expandable and not expanded, expand it.
+ otherwise, act just like the user pressed down */
+ if (selectedItem.Expandable && !selectedItem.Expanded) {
+ selectedItem.Expanded = true;
+ e.Handled = true;
+ break;
+ }
+ else
+ goto case Keys.Down;
+ }
+ case Keys.Enter:
+ /* toggle the expanded state of the selected item */
+ if (selectedItem.Expandable) {
+ selectedItem.Expanded = !selectedItem.Expanded;
+ }
+ e.Handled = true;
+ break;
+ case Keys.Up:
+ property_grid.SelectedGridItem = MoveUpFromItem (selectedItem, 1);
+ e.Handled = true;
+ break;
+ case Keys.Down:
+ property_grid.SelectedGridItem = MoveDownFromItem (selectedItem, 1);
+ e.Handled = true;
+ break;
+ case Keys.PageUp:
+ property_grid.SelectedGridItem = MoveUpFromItem (selectedItem, vbar.LargeChange);
+ e.Handled = true;
+ break;
+ case Keys.PageDown:
+ property_grid.SelectedGridItem = MoveDownFromItem (selectedItem, vbar.LargeChange);
+ e.Handled = true;
+ break;
+ case Keys.End:
+ /* find the last, most deeply nested visible item */
+ GridEntry item = (GridEntry)property_grid.RootGridItem.GridItems[property_grid.RootGridItem.GridItems.Count - 1];
+ while (item.Expandable && item.Expanded)
+ item = (GridEntry)item.GridItems[item.GridItems.Count - 1];
+ property_grid.SelectedGridItem = item;
+ e.Handled = true;
+ break;
+ case Keys.Home:
+ property_grid.SelectedGridItem = property_grid.RootGridItem.GridItems[0];
+ e.Handled = true;
+ break;
+ }
+
+ base.OnKeyDown (e);
}
#endregion
#region Private Helper Methods
- private int SplitterLocation{
+ private int SplitterLocation {
get {
return (int)(splitter_percent*Width);
}
}
- private double SplitterPercent{
+ private double SplitterPercent {
set {
- splitter_percent = Math.Max(Math.Min(value, .9),.1);
+ int old_splitter_location = SplitterLocation;
+
+ splitter_percent = Math.Max (Math.Min (value, .9),.1);
+
+ if (old_splitter_location != SplitterLocation) {
+ int x = old_splitter_location > SplitterLocation ? SplitterLocation : old_splitter_location;
+ Invalidate (new Rectangle (x, 0, Width - x - (vbar.Visible ? vbar.Width : 0), Height));
+ UpdateItem ((GridEntry)property_grid.SelectedGridItem);
+ }
+ }
+ get {
+ return splitter_percent;
}
}
+ private bool GridLabelHitTest (int x)
+ {
+ if (0 <= x && x <= splitter_percent * this.Width)
+ return true;
+ return false;
+ }
+
private GridItem GetSelectedGridItem (GridItemCollection grid_items, int y, ref int current) {
foreach (GridItem child_grid_item in grid_items) {
if (y > current && y < current + row_height) {
}
current += row_height;
if (child_grid_item.Expanded) {
- GridItem foundItem = GetSelectedGridItem(child_grid_item.GridItems, y, ref current);
+ GridItem foundItem = GetSelectedGridItem (child_grid_item.GridItems, y, ref current);
if (foundItem != null)
return foundItem;
}
return null;
}
- private void UpdateScrollBar() {
- int visible_rows = this.ClientRectangle.Height/row_height;
- if (open_grid_item_count > visible_rows) {
+ private int GetVisibleItemsCount (GridEntry entry)
+ {
+ if (entry == null)
+ return 0;
+
+ int count = 0;
+ foreach (GridEntry e in entry.GridItems) {
+ count += 1;
+ if (e.Expandable && e.Expanded)
+ count += GetVisibleItemsCount (e);
+ }
+ return count;
+ }
+
+ private int GetVisibleRowsCount ()
+ {
+ return this.Height / row_height;
+ }
+
+ private void UpdateScrollBar ()
+ {
+ if (property_grid.RootGridItem == null)
+ return;
+
+ int visibleRows = GetVisibleRowsCount ();
+ int openedItems = GetVisibleItemsCount ((GridEntry)property_grid.RootGridItem);
+ if (openedItems > visibleRows) {
vbar.Visible = true;
vbar.SmallChange = 1;
vbar.Minimum = 0;
- vbar.Maximum = open_grid_item_count-1;
- vbar.LargeChange = visible_rows;
- }
- else {
+ vbar.Maximum = openedItems - 1;
+ vbar.LargeChange = visibleRows;
+ } else {
+ vbar.Value = 0;
vbar.Visible = false;
}
-
+ UpdateGridTextBoxBounds ((GridEntry)property_grid.SelectedGridItem);
}
+ // private bool GetScrollBarVisible ()
+ // {
+ // if (property_grid.RootGridItem == null)
+ // return false;
+ //
+ // int visibleRows = GetVisibleRowsCount ();
+ // int openedItems = GetVisibleItemsCount ((GridEntry)property_grid.RootGridItem);
+ // if (openedItems > visibleRows)
+ // return true;
+ // return false;
+ // }
#region Drawing Code
- private void DrawGrid(PaintEventArgs pevent) {
- Pen pen = ThemeEngine.Current.ResPool.GetPen(property_grid.LineColor);
- // vertical divider line
- pevent.Graphics.DrawLine(pen, SplitterLocation, 0, SplitterLocation, (open_grid_item_count-skipped_grid_items)*row_height);
-
- int y = 0;
- while (y < ClientRectangle.Height && y/row_height + skipped_grid_items < open_grid_item_count) {
- // horizontal lines
- pevent.Graphics.DrawLine(pen, 0, y, ClientRectangle.Width, y);
- y += row_height;
- }
- }
-
- private void DrawGridItems(GridItemCollection grid_items, PaintEventArgs pevent, int depth, ref int yLoc) {
+ private void DrawGridItems (GridItemCollection grid_items, PaintEventArgs pevent, int depth, ref int yLoc) {
foreach (GridItem grid_item in grid_items) {
- DrawGridItem (grid_item, pevent, depth, ref yLoc);
+ DrawGridItem ((GridEntry)grid_item, pevent, depth, ref yLoc);
if (grid_item.Expanded)
- DrawGridItems(grid_item.GridItems, pevent, (grid_item.GridItemType == GridItemType.Category) ? depth : depth+1, ref yLoc);
+ DrawGridItems (grid_item.GridItems, pevent, (grid_item.GridItemType == GridItemType.Category) ? depth : depth+1, ref yLoc);
}
}
- private void DrawGridItemLabel(GridItem grid_item, PaintEventArgs pevent, Rectangle rect) {
- int x = rect.X+1;
- if (grid_item.Parent != null && grid_item.Parent.GridItemType != GridItemType.Category)
- x += V_INDENT;
-
+ private void DrawGridItemLabel (GridEntry grid_item, PaintEventArgs pevent, int depth, Rectangle rect) {
Font font = this.Font;
- Brush brush = SystemBrushes.WindowText;
+ Brush brush;
+
if (grid_item.GridItemType == GridItemType.Category) {
font = bold_font;
- brush = SystemBrushes.ControlDark;
- }
+ brush = SystemBrushes.ControlText;
- if (grid_item == property_grid.SelectedGridItem && grid_item.GridItemType != GridItemType.Category) {
- pevent.Graphics.FillRectangle (SystemBrushes.Highlight, rect);
- // Label
- brush = SystemBrushes.HighlightText;
- }
-
-
- if (grid_item.GridItemType == GridItemType.Category) {
- pevent.Graphics.DrawString(grid_item.Label,font,brush,x, rect.Y + 2);
+ pevent.Graphics.DrawString (grid_item.Label, font, brush, rect.X + 1, rect.Y + ENTRY_SPACING);
if (grid_item == property_grid.SelectedGridItem) {
- SizeF size = pevent.Graphics.MeasureString(grid_item.Label, bold_font);
- ControlPaint.DrawFocusRectangle(pevent.Graphics, new Rectangle(x,rect.Y+2, (int)size.Width, (int)size.Height));
+ SizeF size = pevent.Graphics.MeasureString (grid_item.Label, font);
+ ControlPaint.DrawFocusRectangle (pevent.Graphics, new Rectangle (rect.X + 1, rect.Y+ENTRY_SPACING, (int)size.Width, (int)size.Height));
}
}
- else
- pevent.Graphics.DrawString(grid_item.Label,font,brush,new Rectangle(x, rect.Y + 2,x-rect.X+rect.Width-2,rect.Height-2),string_format);
- }
-
- private void DrawGridItemValue(GridItem grid_item, PaintEventArgs pevent, Rectangle rect) {
- // Value
- if (grid_item.PropertyDescriptor != null) {
-
- bool paintsValue = false;
- UITypeEditor editor = null;
- object temp = grid_item.PropertyDescriptor.GetEditor(typeof(UITypeEditor));
- editor = (UITypeEditor)temp;//grid_item.PropertyDescriptor.GetEditor(typeof(UITypeEditor));
- if (editor != null) {
- paintsValue = editor.GetPaintValueSupported();
- }
-
+ else {
if (grid_item == property_grid.SelectedGridItem) {
- grid_textbox.ReadOnly = false;
- grid_textbox.DropDownButtonVisible = false;
- grid_textbox.DialogButtonVisible = false;
- if (editor != null) {
- UITypeEditorEditStyle style = editor.GetEditStyle();
-
- switch (style) {
- case UITypeEditorEditStyle.DropDown:
- grid_textbox.DropDownButtonVisible = true;
- break;
- case UITypeEditorEditStyle.Modal:
- grid_textbox.DialogButtonVisible = true;
- break;
- }
- }
- else {
- try {
- if (grid_item.PropertyDescriptor.Converter != null) {
- if (grid_item.PropertyDescriptor.Converter.GetStandardValuesSupported()) {
-
- grid_textbox.DropDownButtonVisible = true;
- grid_textbox.ReadOnly = true;
- }
- }
- else {
- System.Console.WriteLine("Converter not available for type {0}",grid_item.PropertyDescriptor.PropertyType);
- }
-
- }
- catch (Exception) {
- }
+ Rectangle highlight = rect;
+ if (depth > 1) {
+ highlight.X -= V_INDENT;
+ highlight.Width += V_INDENT;
}
+ pevent.Graphics.FillRectangle (SystemBrushes.Highlight, highlight);
+ // Label
+ brush = SystemBrushes.HighlightText;
}
-
-
-
- int xLoc = SplitterLocation+1;
- if (paintsValue) {
- pevent.Graphics.DrawRectangle(Pens.Black, SplitterLocation+2,rect.Y+2, 20, row_height-4);
- try {
- editor.PaintValue(grid_item.Value, pevent.Graphics, new Rectangle(SplitterLocation+3,rect.Y+3, 19, row_height-5));
- }
- catch (Exception ex) {
- System.Console.WriteLine(ex.Message);
- System.Console.WriteLine("Paint Value failed for type {0}",grid_item.PropertyDescriptor.PropertyType);
- // design time stuff is not playing nice
- }
- xLoc += 27;
+ else {
+ brush = grid_item.IsReadOnly ? inactive_text_brush : SystemBrushes.ControlText;
}
+ }
+ pevent.Graphics.DrawString (grid_item.Label, font, brush,
+ new Rectangle (rect.X + 1, rect.Y + ENTRY_SPACING, rect.Width - ENTRY_SPACING, rect.Height - ENTRY_SPACING),
+ string_format);
+ }
- Font font = this.Font;
- try {
- if (grid_item.PropertyDescriptor.Converter != null) {
- string value = grid_item.PropertyDescriptor.Converter.ConvertToString(grid_item.Value);
- if (grid_item.PropertyDescriptor.CanResetValue(property_grid.SelectedObject))
- font = bold_font;
-
- pevent.Graphics.DrawString(value,font,SystemBrushes.WindowText,new RectangleF(xLoc,rect.Y+2, ClientRectangle.Width-(xLoc), row_height),string_format);
- }
- else {
- System.Console.WriteLine("No converter for type {0}",grid_item.PropertyDescriptor.PropertyType);
- }
-
- }
- catch (Exception) {
- }
- if (grid_item == property_grid.SelectedGridItem && grid_item.GridItemType != GridItemType.Category) {
- grid_textbox.SetBounds(xLoc, rect.Top, ClientRectangle.Width-xLoc - (vbar.Visible ? vbar.Width: 0),row_height);
- }
+ private void DrawGridItemValue (GridEntry grid_item, PaintEventArgs pevent, int depth, Rectangle rect)
+ {
+ if (grid_item.PropertyDescriptor == null)
+ return;
+
+ int xLoc = SplitterLocation+ENTRY_SPACING;
+ if (grid_item.PaintValueSupported) {
+ pevent.Graphics.DrawRectangle (Pens.Black, SplitterLocation + ENTRY_SPACING,
+ rect.Y + 2, VALUE_PAINT_WIDTH + 1, row_height - ENTRY_SPACING*2);
+ grid_item.PaintValue (pevent.Graphics,
+ new Rectangle (SplitterLocation + ENTRY_SPACING + 1,
+ rect.Y + ENTRY_SPACING + 1,
+ VALUE_PAINT_WIDTH, row_height - (ENTRY_SPACING*2 +1)));
+ xLoc += VALUE_PAINT_INDENT;
}
+
+ Font font = this.Font;
+ if (grid_item.IsResetable || !grid_item.HasDefaultValue)
+ font = bold_font;
+ Brush brush = grid_item.IsReadOnly ? inactive_text_brush : SystemBrushes.ControlText;
+ string valueText = grid_item.IsMerged && !grid_item.HasMergedValue ? String.Empty : grid_item.ValueText;
+ pevent.Graphics.DrawString (valueText, font,
+ brush,
+ new RectangleF (xLoc + ENTRY_SPACING, rect.Y + ENTRY_SPACING,
+ ClientRectangle.Width-(xLoc), row_height - ENTRY_SPACING*2),
+ string_format);
}
- private void DrawGridItem (GridItem grid_item, PaintEventArgs pevent, int depth, ref int yLoc) {
+ private void DrawGridItem (GridEntry grid_item, PaintEventArgs pevent, int depth, ref int yLoc) {
if (yLoc > -row_height && yLoc < ClientRectangle.Height) {
- if (grid_item.Expandable) {
- grid_item.PlusMinusBounds = DrawPlusMinus(pevent.Graphics, 3, yLoc+row_height/2-3, grid_item.Expanded, grid_item.GridItemType == GridItemType.Category);
- }
+ // Left column
+ pevent.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (property_grid.LineColor),
+ 0, yLoc, V_INDENT, row_height);
if (grid_item.GridItemType == GridItemType.Category) {
- pevent.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (property_grid.LineColor), depth*V_INDENT,yLoc,ClientRectangle.Width-(depth*V_INDENT), row_height);
+ pevent.Graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (property_grid.CategoryForeColor), depth*V_INDENT,yLoc,ClientRectangle.Width-(depth*V_INDENT), row_height);
+ }
+
+ DrawGridItemLabel (grid_item, pevent,
+ depth,
+ new Rectangle (depth * V_INDENT, yLoc, SplitterLocation - depth * V_INDENT, row_height));
+ DrawGridItemValue (grid_item, pevent,
+ depth,
+ new Rectangle (SplitterLocation + ENTRY_SPACING , yLoc,
+ ClientRectangle.Width - SplitterLocation - ENTRY_SPACING - (vbar.Visible ? vbar.Width : 0),
+ row_height));
+
+ if (grid_item.GridItemType != GridItemType.Category) {
+ Pen pen = ThemeEngine.Current.ResPool.GetPen (property_grid.LineColor);
+ // vertical divider line
+ pevent.Graphics.DrawLine (pen, SplitterLocation, yLoc, SplitterLocation, yLoc + row_height);
+
+ // draw the horizontal line
+ pevent.Graphics.DrawLine (pen, 0, yLoc + row_height, ClientRectangle.Width, yLoc + row_height);
+ }
+
+ if (grid_item.Expandable) {
+ int y = yLoc + row_height / 2 - ENTRY_SPACING + 1;
+ grid_item.PlusMinusBounds = DrawPlusMinus (pevent.Graphics, (depth - 1) * V_INDENT + ENTRY_SPACING + 1,
+ y, grid_item.Expanded, grid_item.GridItemType == GridItemType.Category);
}
- DrawGridItemLabel(grid_item, pevent, new Rectangle(depth*V_INDENT,yLoc, SplitterLocation-depth*V_INDENT, row_height));
- DrawGridItemValue(grid_item, pevent, new Rectangle(SplitterLocation+2,yLoc, ClientRectangle.Width-SplitterLocation-2, row_height));
}
grid_item.Top = yLoc;
yLoc += row_height;
- open_grid_item_count++;
}
private Rectangle DrawPlusMinus (Graphics g, int x, int y, bool expanded, bool category) {
- Rectangle bounds = new Rectangle(x, y, 8, 8);
+ Rectangle bounds = new Rectangle (x, y, 8, 8);
if (!category) g.FillRectangle (Brushes.White, bounds);
Pen pen = ThemeEngine.Current.ResPool.GetPen (property_grid.ViewForeColor);
g.DrawRectangle (pen, bounds);
#endregion
#region Event Handling
- private void RedrawEvent (object sender, System.EventArgs e) {
- Refresh();
+ private void RedrawEvent (object sender, System.EventArgs e)
+ {
+ Refresh ();
}
- private void TextBoxValidating (object sender, CancelEventArgs e) {
- if (this.property_grid.SelectedGridItem != null) {
- PropertyDescriptor desc = property_grid.SelectedGridItem.PropertyDescriptor;
- if (desc != null) {
- try {
- if (desc.Converter != null) {
- SetPropertyValue(desc.Converter.ConvertFromString(grid_textbox.Text));
- }
- else {
- System.Console.WriteLine("No converter for type {0}",desc.PropertyType);
- }
- }
- catch (Exception) {
- Console.WriteLine("Error converting string");
- }
- }
- }
- }
+ // private void TextBoxValidating (object sender, CancelEventArgs e)
+ // {
+ // GridEntry entry = (GridEntry) property_grid.SelectedGridItem;
+ // if (entry != null && entry.IsEditable)
+ // TrySetEntry (entry, grid_textbox.Text);
+ // }
#endregion
- private void ToggleValue() {
- if (property_grid.SelectedGridItem.GridItemType == GridItemType.Property) {
- if (property_grid.SelectedGridItem.PropertyDescriptor != null) {
- if (property_grid.SelectedGridItem.PropertyDescriptor.PropertyType == typeof(bool))
- SetPropertyValue(!(bool)property_grid.SelectedGridItem.Value);
- else if (property_grid.SelectedGridItem.PropertyDescriptor.Converter.GetStandardValuesSupported()){
- System.ComponentModel.TypeConverter.StandardValuesCollection coll =
- (System.ComponentModel.TypeConverter.StandardValuesCollection)property_grid.SelectedGridItem.PropertyDescriptor.Converter.GetStandardValues();
- for (int i = 0; i < coll.Count; i++) {
- if (property_grid.SelectedGridItem.Value.Equals(coll[i])){
- if (i < coll.Count-1)
- SetPropertyValue(coll[i+1]);
- else
- SetPropertyValue(coll[0]);
- break;
- }
-
- }
- }
- }
- }
- }
-
- private void dropdown_form_Deactivate (object sender, EventArgs e) {
- dropdown_form.Hide();
- }
-
- private void listBox_MouseUp(object sender, MouseEventArgs e) {
+ private void listBox_MouseUp (object sender, MouseEventArgs e) {
AcceptListBoxSelection (sender);
}
- private void listBox_KeyDown(object sender, KeyEventArgs e)
+ private void listBox_KeyDown (object sender, KeyEventArgs e)
{
switch (e.KeyData & Keys.KeyCode) {
case Keys.Enter:
AcceptListBoxSelection (sender);
return;
case Keys.Escape:
- dropdown_form.Hide();
+ CloseDropDown ();
return;
}
}
- void AcceptListBoxSelection (object sender) {
- if (this.property_grid.SelectedGridItem != null) {
- PropertyDescriptor desc = property_grid.SelectedGridItem.PropertyDescriptor;
- if (desc != null) {
- SetPropertyValue(((ListBox)sender).SelectedItem);
- }
+ void AcceptListBoxSelection (object sender)
+ {
+ GridEntry entry = this.property_grid.SelectedGridItem as GridEntry;
+ if (entry != null) {
+ grid_textbox.Text = (string) ((ListBox) sender).SelectedItem;
+ if (TrySetEntry (entry, (string) ((ListBox) sender).SelectedItem))
+ UnfocusSelection ();
}
- dropdown_form.Hide();
- Refresh();
+ CloseDropDown ();
}
- private void SetPropertyValue(object newVal) {
- if (this.property_grid.SelectedGridItem != null) {
- PropertyDescriptor desc = property_grid.SelectedGridItem.PropertyDescriptor;
- if (desc != null) {
- object target = property_grid.SelectedObject;
- if (property_grid.SelectedGridItem.Parent != null)
- target = property_grid.SelectedGridItem.Parent.Value;
- desc.SetValue(target, newVal);
- }
- }
- }
+ private void DropDownButtonClicked (object sender, EventArgs e)
+ {
+ GridEntry entry = property_grid.SelectedGridItem as GridEntry;
+ if (entry == null)
+ return;
- private void DropDownButtonClicked (object sender, EventArgs e) {
- UITypeEditor editor = property_grid.SelectedGridItem.PropertyDescriptor.GetEditor (typeof (UITypeEditor)) as UITypeEditor;
- if (editor == null) {
+ if (entry.HasCustomEditor) {
+ entry.EditValue ((IWindowsFormsEditorService) this);
+ } else {
if (dropdown_form.Visible) {
- dropdown_form.Hide ();
+ CloseDropDown ();
}
else {
- dropdown_form.Deactivate +=new EventHandler(dropdown_form_Deactivate);
- ListBox listBox = new ListBox();
- listBox.BorderStyle = BorderStyle.FixedSingle;
- listBox.Dock = DockStyle.Fill;
- int selected_index = 0;
- int i = 0;
- foreach (object obj in property_grid.SelectedGridItem.PropertyDescriptor.Converter.GetStandardValues()) {
- listBox.Items.Add(obj);
- if (property_grid.SelectedGridItem.Value.Equals(obj))
- selected_index = i;
- i++;
+ ICollection std_values = entry.AcceptedValues;
+ if (std_values != null) {
+ ListBox listBox = new ListBox ();
+ listBox.BorderStyle = BorderStyle.FixedSingle;
+ int selected_index = 0;
+ int i = 0;
+ foreach (object obj in std_values) {
+ listBox.Items.Add (obj);
+ if (entry.ValueText != null && entry.ValueText.Equals (obj))
+ selected_index = i;
+ i++;
+ }
+ listBox.Height = row_height * Math.Min (listBox.Items.Count, 15);
+ listBox.Width = ClientRectangle.Width - SplitterLocation - (vbar.Visible ? vbar.Width : 0);
+ listBox.KeyDown += new KeyEventHandler (listBox_KeyDown);
+ listBox.MouseUp+=new MouseEventHandler (listBox_MouseUp);
+ if (std_values.Count > 0)
+ listBox.SelectedIndex = selected_index;
+ DropDownControl (listBox);
}
- listBox.SelectedIndex = selected_index;
- listBox.KeyDown += new KeyEventHandler(listBox_KeyDown);
- listBox.MouseUp+=new MouseEventHandler(listBox_MouseUp);
- dropdown_form.Controls.Clear();
- dropdown_form.Controls.Add(listBox);
- dropdown_form.Location = PointToScreen(new Point(SplitterLocation,grid_textbox.Location.Y+row_height));
- dropdown_form.Width = this.Width - this.SplitterLocation;
- dropdown_form.ActiveControl = listBox;
- dropdown_form.Show();
}
- } else { // use editor
- SetPropertyValueFromUITypeEditor (editor);
}
}
- void SetPropertyValueFromUITypeEditor (UITypeEditor editor)
+ private void DialogButtonClicked (object sender, EventArgs e)
{
- ServiceContainer service_container = new ServiceContainer ();
- service_container.AddService (typeof (IWindowsFormsEditorService), this);
- object value = editor.EditValue (
- new ITypeDescriptorContextImpl (this.property_grid),
- service_container,
- property_grid.SelectedGridItem.Value);
- SetPropertyValue (value);
- }
-
- private void DialogButtonClicked(object sender, EventArgs e) {
- UITypeEditor editor = property_grid.SelectedGridItem.PropertyDescriptor.GetEditor (typeof (UITypeEditor)) as UITypeEditor;
- if (editor != null)
- SetPropertyValueFromUITypeEditor (editor);
+ GridEntry entry = property_grid.SelectedGridItem as GridEntry;
+ if (entry != null && entry.HasCustomEditor)
+ entry.EditValue ((IWindowsFormsEditorService) this);
}
- private void HandleValueChanged(object sender, EventArgs e) {
- if (vbar.Value <= 0) {
- vbar.Value = 0;
- }
- if (vbar.Value > vbar.Maximum-ClientRectangle.Height/row_height) {
- vbar.Value = vbar.Maximum-ClientRectangle.Height/row_height+1;
- }
-
- int scroll_amount = (skipped_grid_items-vbar.Value)*row_height;
- XplatUI.ScrollWindow(Handle, 0, scroll_amount, false);
- skipped_grid_items = vbar.Value;
- if (scroll_amount > 0)
- Invalidate(new Rectangle(0,0,Width,scroll_amount+1));
- else
- Invalidate(new Rectangle(0,Height+scroll_amount-1,Width,1-scroll_amount));
+ private void VScrollBar_HandleValueChanged (object sender, EventArgs e)
+ {
+ UpdateView ();
}
- private void grid_textbox_ToggleValue(object sender, EventArgs e) {
- ToggleValue();
- Invalidate();
+ private void grid_textbox_ToggleValue (object sender, EventArgs args)
+ {
+ ToggleValue ((GridEntry)property_grid.SelectedGridItem);
}
- private void HandleSelectedGridItemChanged(object sender, SelectedGridItemChangedEventArgs e) {
- // Region not working correctly
- //Region clip = new Region();
- //if (property_grid.SelectedGridItem != null)
- // clip.Union(new Rectangle(0,property_grid.SelectedGridItem.Top, ClientRectangle.Width, row_height));
- // clip.Union(new Rectangle(0,property_grid.SelectedGridItem.Top, ClientRectangle.Width, row_height));
+ private void ToggleValue (GridEntry entry)
+ {
+ if (entry != null && !entry.IsReadOnly && entry.GridItemType == GridItemType.Property)
+ entry.ToggleValue ();
+ }
- if (e.NewSelection.GridItemType == GridItemType.Property)
- grid_textbox.Visible = true;
- else
+ internal void UpdateItem (GridEntry entry)
+ {
+ if (entry == null || entry.GridItemType == GridItemType.Category ||
+ entry.GridItemType == GridItemType.Root) {
grid_textbox.Visible = false;
+ InvalidateItem (entry);
+ return;
+ }
- if (e.NewSelection.PropertyDescriptor != null) {
- grid_textbox.Text = e.NewSelection.PropertyDescriptor.Converter.ConvertToString(e.NewSelection.Value);
- if (e.NewSelection.PropertyDescriptor.CanResetValue(property_grid.SelectedObject))
+ if (property_grid.SelectedGridItem == entry) {
+ SuspendLayout ();
+ grid_textbox.Visible = false;
+ if (entry.IsResetable || !entry.HasDefaultValue)
grid_textbox.Font = bold_font;
else
grid_textbox.Font = this.Font;
+
+ if (entry.IsReadOnly) {
+ grid_textbox.DropDownButtonVisible = false;
+ grid_textbox.DialogButtonVisible = false;
+ grid_textbox.ReadOnly = true;
+ grid_textbox.ForeColor = SystemColors.GrayText;
+ } else {
+ grid_textbox.DropDownButtonVisible = entry.AcceptedValues != null ||
+ entry.EditorStyle == UITypeEditorEditStyle.DropDown;
+ grid_textbox.DialogButtonVisible = entry.EditorStyle == UITypeEditorEditStyle.Modal;
+ grid_textbox.ForeColor = SystemColors.ControlText;
+ grid_textbox.ReadOnly = !entry.IsEditable;
+ }
+ UpdateGridTextBoxBounds (entry);
+ grid_textbox.Text = entry.IsMerged && !entry.HasMergedValue ? String.Empty : entry.ValueText;
+ grid_textbox.Visible = true;
+ InvalidateItem (entry);
+ ResumeLayout (false);
+ } else {
+ grid_textbox.Visible = false;
}
+ }
- Invalidate(/*clip*/this.ClientRectangle);
- Update();
+ private void UpdateGridTextBoxBounds (GridEntry entry)
+ {
+ int y = -vbar.Value*row_height;
+ CalculateItemY (entry, property_grid.RootGridItem.GridItems, ref y);
+ int x = SplitterLocation + ENTRY_SPACING + (entry.PaintValueSupported ? VALUE_PAINT_INDENT : 0);
+ grid_textbox.SetBounds (x + ENTRY_SPACING, y + ENTRY_SPACING,
+ ClientRectangle.Width - ENTRY_SPACING - x - (vbar.Visible ? vbar.Width : 0),
+ row_height - ENTRY_SPACING);
}
- private void HandlePropertyValueChanged(object s, PropertyValueChangedEventArgs e) {
- if (e.ChangedItem.PropertyDescriptor != null) {
- grid_textbox.Text = e.ChangedItem.PropertyDescriptor.Converter.ConvertToString(e.ChangedItem.Value);
- if (e.ChangedItem.PropertyDescriptor.CanResetValue(property_grid.SelectedObject))
- grid_textbox.Font = bold_font;
- else
- grid_textbox.Font = this.Font;
+ // Calculates the sum of the heights of all items before the one
+ //
+ private bool CalculateItemY (GridEntry entry, GridItemCollection items, ref int y)
+ {
+ foreach (GridItem item in items) {
+ if (item == entry)
+ return true;
+ y += row_height;
+ if (item.Expandable && item.Expanded)
+ if (CalculateItemY (entry, item.GridItems, ref y))
+ return true;
}
+ return false;
}
-
-
- #endregion
-
- #region IWindowsFormsEditorService Members
+ private void ScrollToItem (GridEntry item)
+ {
+ if (item == null)
+ return;
- public void CloseDropDown() {
- dropdown_form.Hide();
+ int itemY = -vbar.Value*row_height;
+ int value = vbar.Value;;
+ CalculateItemY (item, property_grid.RootGridItem.GridItems, ref itemY);
+ if (itemY < 0) // the new item is above the viewable area
+ value += itemY / row_height;
+ else if (itemY + row_height > Height) // the new item is below the viewable area
+ value += ((itemY + row_height) - Height) / row_height + 1;
+ if (value >= vbar.Minimum && value <= vbar.Maximum)
+ vbar.Value = value;
}
- public void DropDownControl(Control control) {
- Object queue_id;
+ internal void SelectItem (GridEntry oldItem, GridEntry newItem)
+ {
+ if (oldItem != null)
+ InvalidateItemLabel (oldItem);
+ if (newItem != null) {
+ UpdateItem (newItem);
+ ScrollToItem (newItem);
+ } else
+ grid_textbox.Visible = false;
+ }
- dropdown_form.Deactivate +=new EventHandler(dropdown_form_Deactivate);
- dropdown_form.Size = control.Size;
- control.Dock = DockStyle.Fill;
- dropdown_form.Controls.Clear();
- dropdown_form.Controls.Add(control);
- dropdown_form.Location = PointToScreen(new Point(SplitterLocation,grid_textbox.Location.Y+row_height));
- dropdown_form.Width = Width - SplitterLocation;
+ internal void UpdateView ()
+ {
+ UpdateScrollBar ();
+ UpdateItem ((GridEntry)property_grid.SelectedGridItem);
+ Invalidate ();
+ Update ();
+ }
- dropdown_form.Show();
- System.Windows.Forms.MSG msg = new MSG();
- queue_id = XplatUI.StartLoop(Thread.CurrentThread);
- while (XplatUI.GetMessage(queue_id, ref msg, IntPtr.Zero, 0, 0) && dropdown_form.Visible) {
- XplatUI.TranslateMessage(ref msg);
- XplatUI.DispatchMessage(ref msg);
- }
+ internal void ExpandItem (GridEntry item)
+ {
+ UpdateItem ((GridEntry)property_grid.SelectedGridItem);
+ Invalidate (new Rectangle (0, item.Top, Width, Height - item.Top));
}
- public System.Windows.Forms.DialogResult ShowDialog(Form dialog) {
- return dialog.ShowDialog(this);
+ internal void CollapseItem (GridEntry item)
+ {
+ UpdateItem ((GridEntry)property_grid.SelectedGridItem);
+ Invalidate (new Rectangle (0, item.Top, Width, Height - item.Top));
}
- #endregion
+ private void ShowDropDownControl (Control control, bool block)
+ {
+ Object queue_id;
- #region Internal Classes
- internal class ITypeDescriptorContextImpl : System.ComponentModel.ITypeDescriptorContext {
- private PropertyGrid property_grid;
- public ITypeDescriptorContextImpl(PropertyGrid propertyGrid) {
- property_grid = propertyGrid;
- }
- #region ITypeDescriptorContext Members
+ Form owner = FindForm ();
- public void OnComponentChanged() {
- // TODO: Add SystemComp.OnComponentChanged implementation
- }
+ Point location;
+ dropdown_form.Size = control.Size;
+ control.Dock = DockStyle.Fill;
+ dropdown_form.Controls.Add (control);
+ dropdown_form.Width = Math.Max (ClientRectangle.Width - SplitterLocation - (vbar.Visible ? vbar.Width : 0),
+ control.Width);
+ dropdown_form.Location = PointToScreen (new Point (grid_textbox.Right - control.Width, grid_textbox.Location.Y + row_height));
+ RepositionInScreenWorkingArea (dropdown_form);
+ location = dropdown_form.Location;
- public IContainer Container {
- get {
- return property_grid as IContainer;
- }
- }
+ owner.AddOwnedForm (dropdown_form);
- public bool OnComponentChanging() {
- // TODO: Add SystemComp.OnComponentChanging implementation
- return false;
- }
+ dropdown_form.Show ();
- public object Instance {
- get {
- return property_grid.SelectedGridItem.Value;
+ if (dropdown_form.Location != location) {
+ dropdown_form.Location = location;
+ }
+ if (block) {
+ System.Windows.Forms.MSG msg = new MSG ();
+ queue_id = XplatUI.StartLoop (Thread.CurrentThread);
+ while (dropdown_form.Visible && XplatUI.GetMessage (queue_id, ref msg, IntPtr.Zero, 0, 0)) {
+ switch (msg.message) {
+ case Msg.WM_NCLBUTTONDOWN:
+ case Msg.WM_NCMBUTTONDOWN:
+ case Msg.WM_NCRBUTTONDOWN:
+ case Msg.WM_LBUTTONDOWN:
+ case Msg.WM_MBUTTONDOWN:
+ case Msg.WM_RBUTTONDOWN:
+ if (!HwndInControl (dropdown_form, msg.hwnd))
+ CloseDropDown ();
+ break;
+ case Msg.WM_ACTIVATE:
+ case Msg.WM_NCPAINT:
+ if (owner.window.Handle == msg.hwnd)
+ CloseDropDown ();
+ break;
+ }
+ XplatUI.TranslateMessage (ref msg);
+ XplatUI.DispatchMessage (ref msg);
}
+ XplatUI.EndLoop (Thread.CurrentThread);
}
+ }
- public PropertyDescriptor PropertyDescriptor {
- get {
- return property_grid.SelectedGridItem.PropertyDescriptor;
+ private void RepositionInScreenWorkingArea (Form form)
+ {
+ Rectangle workingArea = Screen.FromControl (form).WorkingArea;
+ if (!workingArea.Contains (form.Bounds)) {
+ int x, y;
+ x = form.Location.X;
+ y = form.Location.Y;
+
+ if (form.Location.X < workingArea.X)
+ x = workingArea.X;
+
+ if (form.Location.Y + form.Size.Height > workingArea.Height) {
+ Point aboveTextBox = PointToScreen (new Point (grid_textbox.Right - form.Width, grid_textbox.Location.Y));
+ y = aboveTextBox.Y - form.Size.Height;
}
+
+ form.Location = new Point (x, y);
}
+ }
- #endregion
+ private bool HwndInControl (Control c, IntPtr hwnd)
+ {
+ if (hwnd == c.window.Handle)
+ return true;
+ foreach (Control cc in c.Controls.GetAllControls ()) {
+ if (HwndInControl (cc, hwnd))
+ return true;
+ }
+ return false;
+ }
+ #endregion
- #region IServiceProvider Members
+ #region IWindowsFormsEditorService Members
- public object GetService(Type serviceType) {
- // TODO: Add SystemComp.GetService implementation
- return null;
- }
+ public void CloseDropDown () {
+ Control c = dropdown_form.Controls[0];
+ c.Capture = false;
+ dropdown_form.Hide ();
+ dropdown_form.Controls.Clear ();
+ }
- #endregion
+ public void DropDownControl (Control control) {
+ ShowDropDownControl (control, true);
+ }
+ public System.Windows.Forms.DialogResult ShowDialog (Form dialog) {
+ return dialog.ShowDialog (this);
}
+ #endregion
-
/*
class ComboListBox
*/
internal class PropertyGridDropDown : Form {
protected override CreateParams CreateParams {
get {
- CreateParams cp = base.CreateParams;
+ CreateParams cp = base.CreateParams;
cp.Style = unchecked ((int)(WindowStyles.WS_POPUP | WindowStyles.WS_CLIPSIBLINGS | WindowStyles.WS_CLIPCHILDREN));
cp.ExStyle |= (int)(WindowExStyles.WS_EX_TOOLWINDOW | WindowExStyles.WS_EX_TOPMOST);
return cp;
}
}
-
- #endregion
}
}