📄 dynamictreedebuggerrow.cs
字号:
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using Debugger;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Gui.TreeGrid;
namespace ICSharpCode.SharpDevelop.Services
{
public class DynamicTreeDebuggerRow:DynamicTreeRow
{
// Columns:
// 0 = plus sign
// 1 = icon
// 2 = text
// 3 = value
Variable variable;
Image image;
bool populated = false;
public Variable Variable {
get {
return variable;
}
set {
variable = value;
}
}
public bool ShowValuesInHexadecimal {
get {
return ((WindowsDebugger)DebuggerService.CurrentDebugger).Properties.Get("ShowValuesInHexadecimal", false);
}
set {
((WindowsDebugger)DebuggerService.CurrentDebugger).Properties.Set("ShowValuesInHexadecimal", value);
}
}
public DynamicTreeDebuggerRow()
{
}
bool skipUpdate = true;
public DynamicTreeDebuggerRow(Variable variable)
{
if (variable == null) throw new ArgumentNullException("variable");
this.variable = variable;
this.Shown += delegate {
this.variable.ValueChanged += Update;
if (!skipUpdate) {
DoInPausedState( delegate { Update(); } );
}
skipUpdate = false;
};
this.Hidden += delegate {
this.variable.ValueChanged -= Update;
};
DebuggerGridControl.AddColumns(this.ChildColumns);
this[1].Paint += OnIconPaint;
this[3].FinishLabelEdit += OnLabelEdited;
this[3].MouseDown += OnMouseDown;
Update();
}
void Update(object sender, DebuggerEventArgs e)
{
Update();
}
void Update()
{
image = DebuggerIcons.GetImage(variable);
this[1].Text = ""; // Icon
this[2].Text = variable.Name;
if (ShowValuesInHexadecimal && variable.Value is PrimitiveValue && variable.Value.IsInteger) {
this[3].Text = String.Format("0x{0:X}", (variable.Value as PrimitiveValue).Primitive);
} else {
this[3].Text = variable.Value.AsString;
}
this[3].AllowLabelEdit = variable.Value is PrimitiveValue &&
variable.Value.ManagedType != typeof(string) &&
!(variable is PropertyVariable) &&
!ShowValuesInHexadecimal;
this.ShowPlus = variable.Value.MayHaveSubVariables;
this.ShowMinusWhileExpanded = true;
}
void OnIconPaint(object sender, ItemPaintEventArgs e)
{
if (image != null) {
e.Graphics.DrawImageUnscaled(image, e.ClipRectangle);
}
}
void OnLabelEdited(object sender, DynamicListEventArgs e)
{
PrimitiveValue val = (PrimitiveValue)variable.Value;
string newValue = ((DynamicListItem)sender).Text;
try {
val.Primitive = newValue;
} catch (NotSupportedException) {
MessageBox.Show(WorkbenchSingleton.MainForm, "Can not covert " + newValue + " to " + val.ManagedType.ToString(), "Can not set value");
}
}
void OnMouseDown(object sender, DynamicListMouseEventArgs e)
{
if (e.Button == MouseButtons.Right) {
ContextMenuStrip menu = new ContextMenuStrip();
ToolStripMenuItem copyItem;
copyItem = new ToolStripMenuItem();
copyItem.Text = "Copy value to clipboard";
copyItem.Checked = false;
copyItem.Click += delegate {
ClipboardWrapper.SetText(((DynamicListItem)sender).Text);
};
ToolStripMenuItem hewView;
hewView = new ToolStripMenuItem();
hewView.Text = "Show values in hexadecimal";
hewView.Checked = ShowValuesInHexadecimal;
hewView.Click += delegate {
ShowValuesInHexadecimal = !ShowValuesInHexadecimal;
};
menu.Items.AddRange(new ToolStripItem[] {
copyItem,
hewView
});
menu.Show(e.List, e.Location);
}
}
/// <summary>
/// Called when plus is pressed in debugger tooltip.
/// Sets the data to be show in the next level.
/// </summary>
protected override void OnExpanding(DynamicListEventArgs e)
{
if (!populated) {
DoInPausedState(delegate { Populate(); });
}
}
void DoInPausedState(MethodInvoker action)
{
if (Variable.Debugger.IsPaused) {
action();
} else {
EventHandler<DebuggingPausedEventArgs> onDebuggingPaused = null;
onDebuggingPaused = delegate {
action();
Variable.Debugger.DebuggingPaused -= onDebuggingPaused;
};
Variable.Debugger.DebuggingPaused += onDebuggingPaused;
}
}
void Populate()
{
List<Variable> publicStatic = new List<Variable>();
List<Variable> publicInstance = new List<Variable>();
List<Variable> privateStatic = new List<Variable>();
List<Variable> privateInstance = new List<Variable>();
foreach(Variable variable in this.Variable.SubVariables) {
ClassVariable classVariable = variable as ClassVariable;
if (classVariable == null) {
publicInstance.Add(variable);
} else {
if (classVariable.IsPublic) {
if (classVariable.IsStatic) {
publicStatic.Add(variable);
} else {
publicInstance.Add(variable);
}
} else {
if (classVariable.IsStatic) {
privateStatic.Add(variable);
} else {
privateInstance.Add(variable);
}
}
}
}
this.ChildRows.Clear();
// Private Members
if (privateInstance.Count > 0) {
this.ChildRows.Add(MakeSubMenu("Private Members",
RowsFromVariables(privateInstance)));
}
// Static Members
if (publicStatic.Count > 0 || privateStatic.Count > 0) {
DynamicTreeRow privateStaticSubMenu = MakeSubMenu("Private Static Members",
RowsFromVariables(privateStatic));
this.ChildRows.Add(MakeSubMenu("Static Members",
privateStatic.Count > 0 ? new DynamicListRow[]{privateStaticSubMenu} : new DynamicListRow[]{},
RowsFromVariables(publicStatic)));
}
// Public Members
this.ChildRows.AddRange(RowsFromVariables(publicInstance));
populated = true;
}
IEnumerable<DynamicListRow> RowsFromVariables(IEnumerable<Variable> variables)
{
foreach(Variable variable in variables) {
yield return new DynamicTreeDebuggerRow(variable);
}
}
DynamicTreeRow MakeSubMenu(string name, params IEnumerable<DynamicListRow>[] elements)
{
DynamicTreeRow rootRow = new DynamicTreeRow();
rootRow.ShowMinusWhileExpanded = true;
DebuggerGridControl.AddColumns(rootRow.ChildColumns);
rootRow[2].Text = name;
foreach(IEnumerable<DynamicListRow> rows in elements) {
rootRow.ChildRows.AddRange(rows);
}
return rootRow;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -