⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 menucontrol.cs

📁 chaoshi guan li xitong
💻 CS
📖 第 1 页 / 共 3 页
字号:
				length = this.Height;

			// Is there space for any commands?
			if (length > 0)
			{
				// Count the number of rows needed
				int rows = 0;

				// Number of items on this row
				int columns = 0;

				// Create a collection of drawing objects
				_drawCommands = new ArrayList();

				// Minimum length is a gap on either side of the text
				int cellMinLength = _lengthGap * 2;

				// Each cell is as broad as the whole control
				int cellBreadth = this.Height;
				
				// Accumulate starting position of each cell
				int lengthStart = 0;

				// If the chevron is already displayed then reduce length by its length
				if (_chevronStartCommand != null)
					length -= cellMinLength + _chevronLength;

				// Assume chevron is not needed by default
				_chevronStartCommand = null;

				using(Graphics g = this.CreateGraphics())
				{
					// Count the item we are processing
					int index = 0;

					foreach(MenuCommand command in _menuCommands)
					{
						// Give the command a chance to update its state
						command.OnUpdate(EventArgs.Empty);

						// Ignore items that are marked as hidden
						if (!command.Visible)
							continue;

						int cellLength = 0;

						// Is this a separator?
						if (command.Text == "-")
							cellLength = _separatorWidth;
						else
						{
							// Calculate the text width of the cell
							SizeF dimension = g.MeasureString(command.Text, this.Font);

							// Always add 1 to ensure that rounding is up and not down
							cellLength = cellMinLength + (int)dimension.Width + 1;
						}

						Rectangle cellRect;

						// Create a new position rectangle
						if (_direction == Direction.Horizontal)
							cellRect = new Rectangle(lengthStart, _rowHeight * rows, cellLength, _rowHeight);
						else
							cellRect = new Rectangle(_rowWidth * rows, lengthStart, _rowWidth, cellLength);

						lengthStart += cellLength;
						columns++;

						// If this item is overlapping the control edge and it is not the first
						// item on the line then we should wrap around to the next row.
						if ((lengthStart > length) && (columns > 1))
						{
							if (_multiLine)
							{
								// Move to next row
								rows++;

								// Reset number of items on this column
								columns = 1;

								// Reset starting position of next item
								lengthStart = cellLength;

								// Reset position of this item
								if (_direction == Direction.Horizontal)
								{
									cellRect.X = 0;
									cellRect.Y += _rowHeight;
								}
								else
								{
									cellRect.X += _rowWidth;
									cellRect.Y = 0;
								}
							}
							else
							{
								// Is a tracked item being make invisible
								if (index <= _trackItem)
								{
									// Need to remove tracking of this item
									_trackItem = -1;
								}

								// Remember which item is first for the chevron submenu
								_chevronStartCommand = command;

								if (_direction == Direction.Horizontal)
								{
									cellRect.Y = 0;
									cellRect.Width = cellMinLength + _chevronLength;
									cellRect.X = this.Width - cellRect.Width;
									cellRect.Height = _rowHeight;
								}
								else
								{
									cellRect.X = 0;
									cellRect.Height = cellMinLength + _chevronLength;
									cellRect.Y = this.Height - (cellMinLength + _chevronLength);
									cellRect.Width = _rowWidth;
								}

								// Create a draw command for this chevron
								_drawCommands.Add(new DrawCommand(cellRect));

								// Exit, do not add the current item or any afterwards
								break;
							}
						}

						// Create a drawing object
						_drawCommands.Add(new DrawCommand(command, cellRect));

						index++;
					}
				}

				if (_direction == Direction.Horizontal)
				{
					int controlHeight = (rows + 1) * _rowHeight;

					// Ensure the control is the correct height
					if (this.Height != controlHeight)
						this.Height = controlHeight;
				}
				else
				{
					int controlWidth = (rows + 1) * _rowWidth;

					// Ensure the control is the correct width
					if (this.Width != controlWidth)
						this.Width = controlWidth;
				}				
			}
		}

		protected void DrawCommand(int drawItem, bool tracked)
		{
			// Create a graphics object for drawing
			using(Graphics g = this.CreateGraphics())
				DrawSingleCommand(g, _drawCommands[drawItem] as DrawCommand, tracked);
		}

		internal void DrawSingleCommand(Graphics g, DrawCommand dc, bool tracked)
		{
			Rectangle drawRect = dc.DrawRect;
			MenuCommand mc = dc.MenuCommand;

			// Copy the rectangle used for drawing cell
			Rectangle shadowRect = drawRect;

			// Expand to right and bottom to cover the area used to draw shadows
			shadowRect.Width += _shadowGap;
			shadowRect.Height += _shadowGap;

			// Draw background color over cell and shadow area to the right
			using(SolidBrush back = new SolidBrush(SystemColors.Control))
				g.FillRectangle(back, shadowRect);

			if (!dc.Separator)
			{
				Rectangle textRect;

				// Text rectangle size depends on type of draw command we are drawing
				if (dc.Chevron)
				{
					// Create chevron drawing rectangle
					textRect = new Rectangle(drawRect.Left + _lengthGap, drawRect.Top + _boxExpandUpper,
											 drawRect.Width - _lengthGap * 2, drawRect.Height - (_boxExpandUpper * 2));
				}
				else
				{
					// Create text drawing rectangle
					textRect = new Rectangle(drawRect.Left + _lengthGap, drawRect.Top + _lengthGap,
											 drawRect.Width - _lengthGap * 2, drawRect.Height - _lengthGap * 2);
				}

				if (dc.Enabled)
				{
					// Draw selection 
					if (tracked)
					{
						Rectangle boxRect;

						// Create the rectangle for box around the text
						if (_direction == Direction.Horizontal)
						{
							boxRect = new Rectangle(textRect.Left - _boxExpandSides,
												    textRect.Top - _boxExpandUpper,
												    textRect.Width + _boxExpandSides * 2,
												    textRect.Height + _boxExpandUpper);
						}
						else
						{					
							if (!dc.Chevron)
							{
								boxRect = new Rectangle(textRect.Left,
														textRect.Top - _boxExpandSides,
														textRect.Width - _boxExpandSides,
														textRect.Height + _boxExpandSides * 2);
							}
							else
								boxRect = textRect;
						}

						switch(_style)
						{
						case VisualStyle.IDE:
							if (_selected)
							{
								// Fill the entire inside
								g.FillRectangle(SystemBrushes.ControlLight, boxRect);
								
								int rightLeft = boxRect.Right + 1;
								int rightBottom = boxRect.Bottom;

								if (_drawUpwards && (_direction == Direction.Horizontal))
								{
									// Draw the box around the selection area
									using(Pen dark = new Pen(SystemColors.ControlDark))
										g.DrawRectangle(dark, boxRect.Left, boxRect.Top - _shadowGap, 
															  boxRect.Width, boxRect.Height + _shadowGap);

									// Remove the top line of the selection area
									using(Pen dark = new Pen(SystemColors.ControlLight))
										g.DrawLine(dark, boxRect.Left + 1, boxRect.Top, boxRect.Right - 2, boxRect.Top);

									int rightTop = boxRect.Top;
									int leftLeft = boxRect.Left + _shadowGap;

									SolidBrush shadowBrush;

									// Decide if we need to use an alpha brush
									if (_supportsLayered && (_style == VisualStyle.IDE))
										shadowBrush = new SolidBrush(Color.FromArgb(64, 0, 0, 0));
									else
										shadowBrush = new SolidBrush(SystemColors.ControlDark);

									g.FillRectangle(shadowBrush, new Rectangle(rightLeft, rightTop + _shadowGap - 1, _shadowGap, rightBottom - rightTop - _shadowGap*2));

									shadowBrush.Dispose();
								}
								else
								{
									// Draw the box around the selection area
									using(Pen dark = new Pen(SystemColors.ControlDark))
										g.DrawRectangle(dark, boxRect);

									if (_direction == Direction.Horizontal)
									{
										// Remove the bottom line of the selection area
										using(Pen dark = new Pen(SystemColors.ControlLight))
											g.DrawLine(dark, boxRect.Left, boxRect.Bottom, boxRect.Right, boxRect.Bottom);

										int rightTop = boxRect.Top + _shadowYOffset;

										SolidBrush shadowBrush;

										// Decide if we need to use an alpha brush
										if (_supportsLayered && (_style == VisualStyle.IDE))
											shadowBrush = new SolidBrush(Color.FromArgb(64, 0, 0, 0));
										else
											shadowBrush = new SolidBrush(SystemColors.ControlDark);

										g.FillRectangle(shadowBrush, new Rectangle(rightLeft, rightTop, _shadowGap, rightBottom - rightTop));

										shadowBrush.Dispose();
									}
									else
									{
										// Remove the right line of the selection area
										using(Pen dark = new Pen(SystemColors.ControlLight))
											g.DrawLine(dark, boxRect.Right, boxRect.Top, boxRect.Right, boxRect.Bottom);

										int leftLeft = boxRect.Left + _shadowYOffset;

										SolidBrush shadowBrush;

										// Decide if we need to use an alpha brush
										if (_supportsLayered && (_style == VisualStyle.IDE))
											shadowBrush = new SolidBrush(Color.FromArgb(64, 0, 0, 0));
										else
											shadowBrush = new SolidBrush(SystemColors.ControlDark);

										g.FillRectangle(shadowBrush, new Rectangle(leftLeft, rightBottom+1, rightBottom - leftLeft - _shadowGap, _shadowGap));

										shadowBrush.Dispose();
									}
								}
							}
							else
							{
								using (Pen selectPen = new Pen(ColorUtil.VSNetBorderColor))
								{
									// Draw the selection area in white so can alpha draw over the top
									using (SolidBrush whiteBrush = new SolidBrush(Color.White))
										g.FillRectangle(whiteBrush, boxRect);

									using (SolidBrush selectBrush = new SolidBrush(Color.FromArgb(70, ColorUtil.VSNetBorderColor)))
									{
										// Draw the selection area
										g.FillRectangle(selectBrush, boxRect);

										// Draw a border around the selection area
										g.DrawRectangle(selectPen, boxRect);
									}
								}
							}
							break;
						case VisualStyle.Plain:
							if (_plainAsBlock)
							{
								using (SolidBrush selectBrush = new SolidBrush(ColorUtil.VSNetBorderColor))
									g.FillRectangle(selectBrush, drawRect);
							}
							else
							{
								using(Pen lighlight = new Pen(SystemColors.ControlLightLight),
										  dark = new Pen(SystemColors.ControlDark))
								{
									if (_selected)
									{
										g.DrawLine(dark, boxRect.Left, boxRect.Bottom, boxRect.Left, boxRect.Top);
										g.DrawLine(dark, boxRect.Left, boxRect.Top, boxRect.Right, boxRect.Top);
										g.DrawLine(lighlight, boxRect.Right, boxRect.Top, boxRect.Right, boxRect.Bottom);
										g.DrawLine(lighlight, boxRect.Right, boxRect.Bottom, boxRect.Left, boxRect.Bottom);
									}
									else
									{
										g.DrawLine(lighlight, boxRect.Left, boxRect.Bottom, boxRect.Left, boxRect.Top);
										g.DrawLine(lighlight, boxRect.Left, boxRect.Top, boxRect.Right, boxRect.Top);
										g.DrawLine(dark, boxRect.Right, boxRect.Top, boxRect.Right, boxRect.Bottom);
										g.DrawLine(dark, boxRect.Right, boxRect.Bottom, boxRect.Left, boxRect.Bottom);
									}
								}
							}
							break;
						}
					}
				}

				if (dc.Chevron)
				{
					// Draw the chevron image in the centre of the text area
					int yPos = drawRect.Top;
					int xPos = drawRect.X + ((drawRect.Width - _chevronLength) / 2);

					// When selected...
					if (_selected)
					{
						// ...offset down and to the right
						xPos += 1;
						yPos += 1;
					}

					g.DrawImage(_menuImages.Images[_chevronIndex], xPos, yPos);
				}
				else
				{	
					// Left align the text drawing on a single line centered vertically
					// and process the & character to be shown as an underscore on next character
					StringFormat format = new StringFormat();
					format.FormatFlags = StringFormatFlags.NoClip | StringFormatFlags.NoWrap;
					format.Alignment = StringAlignment.Center;
					format.LineAlignment = StringAlignment.Center;
					format.HotkeyPrefix = HotkeyPrefix.Show;

					if (_direction == Direction.Vertical)
						format.FormatFlags |= StringFormatFlags.DirectionVertical;


					if (dc.Enabled)
					{
						if (tracked && (_style == VisualStyle.Plain) && _plainAsBlock)
						{
							// Is the item selected as well as tracked?
							if (_selected)
							{
								// Offset to show it is selected
								textRect.X += 2;
								textRect.Y += 2;
							}

							using (SolidBrush textBrush = new SolidBrush(SystemColors.HighlightText))
								g.DrawString(mc.Text, this.Font, textBrush, textRect, format);
						}
						else
							using (SolidBrush textBrush = new SolidBrush(SystemColors.MenuText))
								g.DrawString(mc.Text, this.Font, textBrush, textRect, format);
					}
					else 
					{
						// Helper values used when drawing grayed text in plain style
						Rectangle rectDownRight = textRect;
						rectDownRight.Offset(1,1);

						// Draw then text offset down and right
						using (SolidBrush whiteBrush = new SolidBrush(SystemColors.HighlightText))
							g.DrawString(mc.Text, this.Font, whiteBrush, rectDownRight, format);

						// Draw then text offset up and left
						using (SolidBrush grayBrush = new SolidBrush(SystemColors.GrayText))
							g.DrawString(mc.Text, this.Font, grayBrush, textRect, format);
					}
				}
			}
		}

		protected void DrawAllCommands(Graphics g)
		{
			for(int i=0; i<_drawCommands.Count; i++)
			{
				// Grab some commonly used values				
				DrawCommand dc = _drawCommands[i] as DrawCommand;

				// Draw this command only
				DrawSingleCommand(g, dc, (i == _trackItem));
			}
		}

		protected int SwitchTrackingItem(int oldItem, int newItem)
		{
			// Create a graphics object for drawinh
			using(Graphics g = this.CreateGraphics())
			{
				// Deselect the old draw command
				if (oldItem != -1)
				{
					DrawCommand dc = _drawCommands[oldItem] as DrawCommand;

					// Draw old item not selected
					DrawSingleCommand(g, _drawCommands[oldItem] as DrawCommand, false);
				}

				_trackItem = newItem;

				// Select the new draw command
				if (_trackItem != -1)
				{
					DrawCommand dc = _drawCommands[_trackItem] as DrawCommand;

					// Draw new item selected
					DrawSingleCommand(g, _drawCommands[_trackItem] as DrawCommand, true);
				}
			}

			return _trackItem;
		}

		internal void OperateSubMenu(DrawCommand dc, bool selectFirst, bool trackRemove)
		{
			Rectangle drawRect = dc.DrawRect;

			// Find screen positions for popup menu
			Point screenPos;
			
			if (_style == VisualStyle.IDE)
			{
				if (_direction == Direction.Horizontal)
					screenPos = PointToScreen(new Point(dc.DrawRect.Left + 1, drawRect.Bottom - _lengthGap - 1));
				else
					screenPos = PointToScreen(new Point(dc.DrawRect.Right - _breadthGap, drawRect.Top + _boxExpandSides - 1));
			}
			else
			{
				if (_direction == Direction.Horizontal)
					screenPos = PointToScreen(new Point(dc.DrawRect.Left + 1, drawRect.Bottom));
				else
					screenPos = PointToScreen(new Point(dc.DrawRect.Right, drawRect.Top));
			}

			Point aboveScreenPos;
			
			if (_style == VisualStyle.IDE)
			{
				if (_direction == Direction.Horizontal)
					aboveScreenPos = PointToScreen(new Point(dc.DrawRect.Left + 1, drawRect.Top + _lengthGap + 1));
				else
					aboveScreenPos = PointToScreen(new Point(dc.DrawRect.Right - _breadthGap, drawRect.Bottom + _lengthGap));
			}
			else
			{
				if (_direction == Direction.Horizontal)
					aboveScreenPos = PointToScreen(new Point(dc.DrawRect.Left + 1, drawRect.Top));
				else
					aboveScreenPos = PointToScreen(new Point(dc.DrawRect.Right, drawRect.Bottom));
			}

			int borderGap;

			// Calculate the missing gap in the PopupMenu border
			if (_direction == Direction.Horizontal)
				borderGap = dc.DrawRect.Width - _subMenuBorderAdjust;
			else
				borderGap = dc.DrawRect.Height - _subMenuBorderAdjust;		
	
			_popupMenu = new PopupMenu();

			// Define the correct visual style based on ours
			_popupMenu.Style = this.Style;

			// Key direction when keys cause dismissal
			int returnDir = 0;

			if (dc.Chevron)
			{
				MenuCommandCollection mcc = new MenuCommandCollection();

				bool addCommands = false;

				// Generate a collection of menu commands for those not visible
				foreach(MenuCommand command in _menuCommands)
				{
					if (!addCommands && (command == _chevronStartCommand))
						addCommands = true;

					if (addCommands)
						mcc.Add(command);
				}

				// Track the popup using provided menu item collection
				_popupMenu.TrackPopup(screenPos, 
									  aboveScreenPos,
									  _direction,
									  mcc, 
									  borderGap,
									  selectFirst,
									  this,
									  ref returnDir);
			}
			else
			{
				// Generate event so that caller has chance to modify MenuCommand contents
				OnPopupStart(dc.MenuCommand);

				// Track the popup using provided menu item collection

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -