增强型DataSet Quick Watch






4.73/5 (14投票s)
一个 VS.NET 插件,用于在调试时可视化标准和类型化的 DataSet、DataTable 和 DataRow。
引言
这个插件本质上是对 Mohammed Barqawi 的优秀DataSet 快速监视插件的更新。 请参考该文章了解原始概念和代码。
该插件的实现非常棒,但明显不支持类型化的数据集。 我添加了一些东西,使原始想法更进一步,并希望使调试时可视化数据集的生活更加轻松。
有什么新功能?
类型化 DataSet 支持 |
这允许所有类型化的 DataSet(直接继承自 |
支持 DataTables 和 DataRows |
这允许您(在代码中)选择一个表或行,并加载数据集(在输出中选择该表或行)。 |
行筛选器支持 |
还添加了自由文本行筛选器和“ |
视觉增强 |
DataSet Watch 窗体已修改为使用自定义“ 我还没有完全完成添加用户首选项支持! |
使用代码
调试器表达式
最初的概念仍然存在,但我对我们获取和检查调试器表达式的方式进行了一些修改。 我重构了每个表达式的构造,使其基于输入语言工作
private string GetEvaluationExpression(string type, object selectedObject,
string propOrMethod, string SourceType)
{
switch (SourceType)
{
case LangCSharp:
{
return "(" + type + ")" + selectedObject + propOrMethod;
}
case LangVB:
{
if (type == "int")
type = "System.Int32";
//HACK to cope with language differences
return "ctype(" + selectedObject + ", "
+ type + ")" + propOrMethod;
}
default :
{
throw new ApplicationException("Invalid Source Type : "
+ "Expected 'cs' or 'vb'");
}
}
}
其中 str
(调试器中选定的文本) == "myDataTable"
,下面这行将为 getTableNameFromTableExpression
分配一个特定于语言的调试器表达式字符串
getTableNameFromTableExpression =
GetEvaluationExpression(TypeDataTable, str, ".TableName", fileExtension);
- C# -
System.Data.DataTable)myDataTable.TableName
- VB -
ctype(System.Data.DataTable, myDataTable).TableName
这个特定的表达式用于从选定的 DataTable
获取表名。
类型化的 DataSets
当我们评估返回意外类型的表达式时,会提供对类型化数据集的支持。 发生这种情况是因为调试器返回您选择的表达式的“实际”类型 - 例如,MyNamespace.MyTypedDataSet.MyTableRow
。
如果您选择的不是 DataSet
、DataTable
或 DataRow
(或任何直接派生自这些类型的),则 ExpressionHasError
方法会在表达式的值中找到文本 "error:"
。
如果返回一个类型化的数据对象(并且我们返回类型名称),则我们找到基类型并再次评估该表达式...如果它是一个类型化的数据集、表或行,那么我们应该第二次找到正确的 (System.Data...
) 类型。
// Calling code..... Filtering down -
// checking for DataSet, then DataTable, then DataRow
//Check which worked!
if (ExpressionHasError(exprDataSet, "{System.Data.DataSet}", str))
{
//Check for DataTable
if (ExpressionHasError(exprDataTable, "{System.Data.DataTable}", str))
{
//Check for DataRow
if (ExpressionHasError(exprDataRow, "{System.Data.DataRow}", str))
{
MessageBox.Show("This is not a DataSet, DataTable or DataRow!",
"DSWatch",MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
//.....
private bool ExpressionHasError(Expression expr,
string type, string originalContext)
{
EnvDTE.Debugger debugger = applicationObject.Debugger;
if (type != null)
if (expr.Value.IndexOf("error:")>-1)
return true;
else
{
if (expr.Value != type)
{
//Check for base type (only going one level down
// - so assume here that every 'typed' dataset
//is a direct descendent of System.Data.DataSet
//need to remove any quotes if we're in a recursive call
Expression baseExpression =
debugger.GetExpression(originalContext +
".GetType().BaseType.Name" , true, 500);
string val = baseExpression.Value.Replace("\"", String.Empty);
string subType = type.Substring(type.LastIndexOf(".")
+1).Replace("}", String.Empty);
return (val != subType);
}
else
//All is OK
return false;
}
else
return expr.Value.IndexOf("error:")>-1;
}
选择特定行
如果我们在调试器中通过变量选择了行:myRow
或使用索引器:myDataSet.Tables[0].Rows[0]
,我们知道可以通过 rowID
属性找到该行(在表中)的序号位置。 然后,我们可以使用此信息在输出窗体中选择相应的行(和表)。
行筛选
这与标准 DataView
筛选(使用自由文本行筛选器)和 DataViewRowState
筛选器(用于显示特定状态下的所有行)结合使用。 以下应用了两个筛选器的组合。
private void ApplyFilter(bool showAll)
{
try
{
if (_dataSource == null)
return;
//Filter the contents of the grid
if (showAll || (this.rowStateFilter.SelectedIndex == 0 &&
this.rowFilterExpression.Text == String.Empty))
_view = _dataSource.DefaultView;
else
{
_view = new DataView(_dataSource);
if (this.rowStateFilter.SelectedIndex != 0)
_view.RowStateFilter =
(DataViewRowState)Enum.Parse(typeof(DataViewRowState),
this.rowStateFilter.SelectedItem.ToString(), true);
_view.RowFilter = this.rowFilterExpression.Text;
}
this.grid.DataSource = _view;
if (this.FilterChanged != null)
this.FilterChanged(this.grid,
new FilterChangedEventArgs(_dataSource,
_view.Count, _dataSource.Rows.Count - _view.Count));
this.grid.Refresh();
}
catch (Exception ex)
{
MessageBox.Show(String.Format("There was a problem" +
" applying the row filter\n\n{0}", ex.Message),
"Row Filter", MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
}
}
EnhancedGrid
UserControl 定义了一个 FilterChanged
事件,传递上下文信息以允许父窗体更改其状态栏中的文本。