using System; using System.Collections.Generic; using System.Data; using System.Data.SQLite; // 替换 Microsoft.Data.Sqlite using System.Globalization; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Quicker.Public;
privateconststring ObjectListSql = "SELECT name, type " + "FROM sqlite_master " + "WHERE type IN ('table', 'view') " + "AND name NOT LIKE 'sqlite_%' " + "ORDER BY name COLLATE NOCASE";
DataTable table; int rowCount; string error; if (!TryQuery(GetText(dataContext, "dbPath"), sql, out table, out rowCount, out error))
{ SetStatus(win, dataContext, "查询失败:" + error); return;
}
var rowCountCache = GetRowCountCache(dataContext); long totalRowCount; if (!rowCountCache.TryGetValue(objectName, out totalRowCount))
{ string countError; if (TryGetObjectRowCount(GetText(dataContext, "dbPath"), objectName, out totalRowCount, out countError))
{
rowCountCache[objectName] = totalRowCount;
} else
{
totalRowCount = -1L;
rowCountCache[objectName] = totalRowCount;
}
}
if (!IsSingleSelect(sql))
{ SetStatus(win, dataContext, "只允许单条 SELECT 查询,且不要输入分号"); return;
}
SetStatus(win, dataContext, "正在执行自定义查询...");
DataTable table; int rowCount; string error; if (!TryQuery(GetText(dataContext, "dbPath"), sql, out table, out rowCount, out error))
{ SetStatus(win, dataContext, "查询失败:" + error); return;
}
privatestaticstringFormatCellValue(objectvalue)
{ if (value == null || value == DBNull.Value) return"NULL"; var bytes = valueasbyte[]; if (bytes != null) return Convert.ToBase64String(bytes); returnFormatJsonIfPossible(Convert.ToString(value));
}
privatestaticstringFormatJsonIfPossible(stringvalue)
{ if (String.IsNullOrWhiteSpace(value)) returnvalue; var text = value.Trim(); if (!((text.StartsWith("{") && text.EndsWith("}")) || (text.StartsWith("[") && text.EndsWith("]")))) returnvalue;
var captionText = win.FindName("CellCaptionText") as TextBlock; if (captionText != null) captionText.Text = caption;
var valueBox = win.FindName("CellValueBox") as TextBox; if (valueBox != null) valueBox.Text = value;
}
privatestaticvoidSetSqlText(Window win, IDictionary<string, object> dataContext, string sql)
{
dataContext["sql"] = sql; var sqlBox = win.FindName("SqlBox") as TextBox; if (sqlBox != null) sqlBox.Text = sql;
}
privatestaticvoidSetCurrentObject(Window win, IDictionary<string, object> dataContext, string text)
{ var label = win.FindName("CurrentObjectText") as TextBlock; if (label != null) label.Text = text;
}
privatestaticvoidSetPageText(Window win, int offset, int pageSize, int rowCount, long totalRowCount)
{ var label = win.FindName("PageText") as TextBlock; if (label == null) return;
//css_ref System.Data.SQLite.dll
//css_ref Newtonsoft.Json.dll
//css_ref WindowsBase.dll
//css_ref PresentationCore.dll
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite; // 替换 Microsoft.Data.Sqlite
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Quicker.Public;
public static class Script
{
private const int PageSize = 100;
private const int ResultCellPreviewLength = 120;
private const double ResultColumnMaxWidth = 280;
private static readonly IValueConverter ResultPreviewConverter = new ResultPreviewValueConverter();
private sealed class ResultPreviewValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var text = value as string;
return text == null ? value : GetResultCellPreview(text);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return Binding.DoNothing;
}
}
private const string ObjectListSql =
"SELECT name, type " +
"FROM sqlite_master " +
"WHERE type IN ('table', 'view') " +
"AND name NOT LIKE 'sqlite_%' " +
"ORDER BY name COLLATE NOCASE";
// ---------- 入口方法 ----------
public static void OnWindowCreated(
Window win,
IDictionary<string, object> dataContext,
ICustomWindowContext winContext)
{
// 初始化数据上下文默认值
dataContext["objectList"] = new DataTable();
dataContext["queryResult"] = new DataTable();
dataContext["fullQueryResult"] = new DataTable();
dataContext["resultSchemaKey"] = "";
dataContext["selectedObject"] = "";
dataContext["sql"] = "";
dataContext["pageSize"] = PageSize;
dataContext["pageOffset"] = 0;
dataContext["totalRowCount"] = 0L;
dataContext["rowCountCache"] = new Dictionary<string, long>(StringComparer.OrdinalIgnoreCase);
dataContext["sortColumn"] = "";
dataContext["sortDescending"] = false;
dataContext["isTablePreview"] = false;
dataContext["currentCellCaption"] = "";
dataContext["currentCellValue"] = "";
dataContext["hasCurrentCell"] = false;
SetObjectList(win, dataContext, (DataTable)dataContext["objectList"]);
SetResultGrid(win, dataContext, (DataTable)dataContext["queryResult"]);
SetCurrentObject(win, dataContext, "选择一个表或视图");
SetPageText(win, 0, PageSize, 0, 0L);
SetCellValue(win, dataContext, "单击上方表格中的单元格以查看完整值", "", false);
SetStatus(win, dataContext, "正在加载数据库对象...");
// ---------- ObjectList 选择事件 ----------
var objectList = win.FindName("ObjectList") as ListBox;
if (objectList != null)
{
objectList.SelectionChanged += delegate (object sender, SelectionChangedEventArgs e)
{
var row = objectList.SelectedItem as DataRowView;
if (row == null || row.Row == null) return;
var objectName = Convert.ToString(row["name"]);
dataContext["sortColumn"] = "";
dataContext["sortDescending"] = false;
ClearSortIndicators(win.FindName("ResultGrid") as DataGrid);
LoadObjectPage(win, dataContext, objectName, 0, false);
};
}
// ---------- ResultGrid 事件 ----------
var resultGrid = win.FindName("ResultGrid") as DataGrid;
if (resultGrid != null)
{
resultGrid.AutoGeneratingColumn += delegate (object sender, DataGridAutoGeneratingColumnEventArgs e)
{
e.Column.MaxWidth = ResultColumnMaxWidth;
var textColumn = e.Column as DataGridTextColumn;
if (textColumn != null)
{
var binding = textColumn.Binding as Binding;
if (binding != null)
binding.Converter = ResultPreviewConverter;
var style = new Style(typeof(TextBlock));
style.Setters.Add(new Setter(TextBlock.TextTrimmingProperty, TextTrimming.CharacterEllipsis));
textColumn.ElementStyle = style;
}
};
resultGrid.LoadingRow += delegate (object sender, DataGridRowEventArgs e)
{
var pageOffset = GetInteger(dataContext, "pageOffset", 0);
e.Row.Header = (pageOffset + e.Row.GetIndex() + 1).ToString();
};
resultGrid.SelectedCellsChanged += delegate (object sender, SelectedCellsChangedEventArgs e)
{
if (e.AddedCells.Count == 0) return;
var cell = e.AddedCells[0];
try
{
ShowCellValue(win, dataContext, cell.Item as DataRowView, cell.Column);
}
catch (Exception ex)
{
SetStatus(win, dataContext, "读取单元格失败:" + ex.Message);
}
};
resultGrid.Sorting += delegate (object sender, DataGridSortingEventArgs e)
{
e.Handled = true;
if (!GetBoolean(dataContext, "isTablePreview"))
{
SetStatus(win, dataContext, "请先从左侧选择表或视图");
return;
}
var columnName = GetColumnName(e.Column);
var sameColumn = String.Equals(
GetText(dataContext, "sortColumn"),
columnName,
StringComparison.OrdinalIgnoreCase);
var currentDescending = GetBoolean(dataContext, "sortDescending");
if (sameColumn && currentDescending)
{
dataContext["sortColumn"] = "";
dataContext["sortDescending"] = false;
}
else
{
dataContext["sortColumn"] = columnName;
dataContext["sortDescending"] = sameColumn;
}
var selectedObject = GetText(dataContext, "selectedObject");
if (!String.IsNullOrWhiteSpace(selectedObject))
LoadObjectPage(win, dataContext, selectedObject, 0, false);
};
}
RefreshObjects(win, dataContext);
}
// ---------- 按钮点击处理 ----------
public static bool OnButtonClicked(
string controlName,
object controlTag,
Window win,
IDictionary<string, object> dataContext,
ICustomWindowContext winContext)
{
if (controlName == "btnRefreshObjects")
{
RefreshObjects(win, dataContext);
return true;
}
if (controlName == "btnCopyCell")
{
CopyCurrentCell(win, dataContext);
return true;
}
var selectedObject = GetText(dataContext, "selectedObject");
var pageSize = PageSize;
var pageOffset = GetInteger(dataContext, "pageOffset", 0);
if (controlName == "btnPrevious")
{
if (String.IsNullOrWhiteSpace(selectedObject))
{
SetStatus(win, dataContext, "请先选择一个表或视图");
return true;
}
LoadObjectPage(win, dataContext, selectedObject, Math.Max(0, pageOffset - pageSize), false);
return true;
}
if (controlName == "btnNext")
{
if (String.IsNullOrWhiteSpace(selectedObject))
{
SetStatus(win, dataContext, "请先选择一个表或视图");
return true;
}
LoadObjectPage(win, dataContext, selectedObject, pageOffset + pageSize, true);
return true;
}
if (controlName == "btnRunSql")
{
RunCustomSelect(win, dataContext);
return true;
}
return false;
}
// ---------- 核心数据访问(使用 System.Data.SQLite) ----------
private static bool TryQuery(string dbPath, string sql, out DataTable table, out int rowCount, out string error)
{
table = new DataTable();
rowCount = 0;
error = "未知错误";
if (String.IsNullOrWhiteSpace(dbPath))
{
error = "没有选择数据库文件";
return false;
}
if (String.IsNullOrWhiteSpace(sql))
{
error = "SQL 不能为空";
return false;
}
try
{
var connectionString = new SQLiteConnectionStringBuilder
{
DataSource = dbPath,
ReadOnly = true,
Pooling = true
}.ToString();
using (var connection = new SQLiteConnection(connectionString))
using (var command = connection.CreateCommand())
{
command.CommandText = sql;
command.CommandTimeout = 30;
connection.Open();
using (var reader = command.ExecuteReader())
{
table.Load(reader);
}
}
rowCount = table.Rows.Count;
error = "";
return true;
}
catch (Exception ex)
{
error = ex.Message;
return false;
}
}
private static bool TryGetObjectRowCount(string dbPath, string objectName, out long totalRowCount, out string error)
{
totalRowCount = 0L;
var countSql = "SELECT COUNT(*) AS total_rows FROM " + QuoteIdentifier(objectName);
DataTable countTable;
int ignoredRowCount;
if (!TryQuery(dbPath, countSql, out countTable, out ignoredRowCount, out error))
return false;
if (countTable.Rows.Count == 0 || !countTable.Columns.Contains("total_rows"))
{
error = "总行数查询没有返回 total_rows";
return false;
}
try
{
totalRowCount = Convert.ToInt64(countTable.Rows[0]["total_rows"]);
error = "";
return true;
}
catch (Exception ex)
{
error = ex.Message;
return false;
}
}
// ---------- 业务逻辑方法(保持不变) ----------
private static void RefreshObjects(Window win, IDictionary<string, object> dataContext)
{
SetStatus(win, dataContext, "正在读取表和视图...");
DataTable table;
int rowCount;
string error;
if (!TryQuery(GetText(dataContext, "dbPath"), ObjectListSql, out table, out rowCount, out error))
{
SetObjectList(win, dataContext, new DataTable());
dataContext["selectedObject"] = "";
dataContext["pageOffset"] = 0;
dataContext["totalRowCount"] = 0L;
dataContext["rowCountCache"] = new Dictionary<string, long>(StringComparer.OrdinalIgnoreCase);
dataContext["sortColumn"] = "";
dataContext["sortDescending"] = false;
dataContext["isTablePreview"] = false;
SetResultGrid(win, dataContext, new DataTable());
ClearSortIndicators(win.FindName("ResultGrid") as DataGrid);
SetCurrentObject(win, dataContext, "选择一个表或视图");
SetPageText(win, 0, PageSize, 0, 0L);
SetCellValue(win, dataContext, "单击上方表格中的单元格以查看完整值", "", false);
SetStatus(win, dataContext, "读取对象失败:" + error);
return;
}
SetObjectList(win, dataContext, table);
dataContext["selectedObject"] = "";
dataContext["pageOffset"] = 0;
dataContext["totalRowCount"] = 0L;
dataContext["rowCountCache"] = new Dictionary<string, long>(StringComparer.OrdinalIgnoreCase);
dataContext["sortColumn"] = "";
dataContext["sortDescending"] = false;
dataContext["isTablePreview"] = false;
SetResultGrid(win, dataContext, new DataTable());
ClearSortIndicators(win.FindName("ResultGrid") as DataGrid);
SetCurrentObject(win, dataContext, "选择一个表或视图");
SetPageText(win, 0, PageSize, 0, 0L);
SetCellValue(win, dataContext, "单击上方表格中的单元格以查看完整值", "", false);
SetStatus(win, dataContext, "已发现 " + rowCount + " 个表或视图");
}
private static void LoadObjectPage(Window win, IDictionary<string, object> dataContext, string objectName, int offset, bool keepCurrentPageWhenEmpty)
{
if (String.IsNullOrWhiteSpace(objectName))
{
SetStatus(win, dataContext, "未取得对象名称");
return;
}
var pageSize = PageSize;
offset = Math.Max(0, offset);
var orderBy = GetTableOrderBy(GetText(dataContext, "sortColumn"), GetBoolean(dataContext, "sortDescending"));
var sql = "SELECT * FROM " + QuoteIdentifier(objectName) + orderBy +
" LIMIT " + pageSize + " OFFSET " + offset;
SetStatus(win, dataContext, "正在读取 " + objectName + "...");
DataTable table;
int rowCount;
string error;
if (!TryQuery(GetText(dataContext, "dbPath"), sql, out table, out rowCount, out error))
{
SetStatus(win, dataContext, "查询失败:" + error);
return;
}
var rowCountCache = GetRowCountCache(dataContext);
long totalRowCount;
if (!rowCountCache.TryGetValue(objectName, out totalRowCount))
{
string countError;
if (TryGetObjectRowCount(GetText(dataContext, "dbPath"), objectName, out totalRowCount, out countError))
{
rowCountCache[objectName] = totalRowCount;
}
else
{
totalRowCount = -1L;
rowCountCache[objectName] = totalRowCount;
}
}
dataContext["totalRowCount"] = totalRowCount;
if (keepCurrentPageWhenEmpty && rowCount == 0)
{
SetStatus(win, dataContext, "已是最后一页");
return;
}
dataContext["selectedObject"] = objectName;
dataContext["pageOffset"] = offset;
dataContext["isTablePreview"] = true;
SetCurrentObject(win, dataContext, objectName);
SetSqlText(win, dataContext, sql);
SetResultGrid(win, dataContext, table);
ApplyCurrentSortIndicator(win.FindName("ResultGrid") as DataGrid, GetText(dataContext, "sortColumn"), GetBoolean(dataContext, "sortDescending"));
SetCellValue(win, dataContext, "单击上方表格中的单元格以查看完整值", "", false);
SetPageText(win, offset, pageSize, rowCount, totalRowCount);
SetStatus(win, dataContext,
"已加载 " + objectName + ",本页 " + rowCount + " 行" +
(totalRowCount >= 0 ? ",总计 " + totalRowCount + " 行" : ",总行数读取失败"));
}
private static void RunCustomSelect(Window win, IDictionary<string, object> dataContext)
{
var sql = GetText(dataContext, "sql");
if (String.IsNullOrWhiteSpace(sql))
{
SetStatus(win, dataContext, "请输入一条 SELECT 查询");
return;
}
if (!IsSingleSelect(sql))
{
SetStatus(win, dataContext, "只允许单条 SELECT 查询,且不要输入分号");
return;
}
SetStatus(win, dataContext, "正在执行自定义查询...");
DataTable table;
int rowCount;
string error;
if (!TryQuery(GetText(dataContext, "dbPath"), sql, out table, out rowCount, out error))
{
SetStatus(win, dataContext, "查询失败:" + error);
return;
}
dataContext["pageOffset"] = 0;
SetResultGrid(win, dataContext, table);
dataContext["isTablePreview"] = false;
SetCurrentObject(win, dataContext, "自定义 SELECT 查询");
SetCellValue(win, dataContext, "单击上方表格中的单元格以查看完整值", "", false);
SetPageText(win, 0, PageSize, rowCount, (long)rowCount);
SetStatus(win, dataContext, "自定义查询完成,共 " + rowCount + " 行");
}
// ---------- 辅助方法 ----------
private static bool IsSingleSelect(string sql)
{
var text = sql.TrimStart();
if (text.IndexOf(';') >= 0 || !text.StartsWith("select", StringComparison.OrdinalIgnoreCase))
return false;
if (text.Length == 6) return false;
var nextChar = text[6];
return !Char.IsLetterOrDigit(nextChar) && nextChar != '_';
}
private static string QuoteIdentifier(string identifier)
{
return "\"" + identifier.Replace("\"", "\"\"") + "\"";
}
private static string GetColumnName(DataGridColumn column)
{
if (column == null) return "";
if (!String.IsNullOrWhiteSpace(column.SortMemberPath))
return column.SortMemberPath;
return RemoveSortArrow(Convert.ToString(column.Header));
}
private static string RemoveSortArrow(string header)
{
var text = header ?? "";
if (text.EndsWith(" ▲") || text.EndsWith(" ▼"))
return text.Substring(0, text.Length - 2);
return text;
}
private static string GetTableOrderBy(string columnName, bool descending)
{
if (String.IsNullOrWhiteSpace(columnName)) return "";
return " ORDER BY " + QuoteIdentifier(columnName) + (descending ? " DESC" : " ASC");
}
private static void SetSortIndicator(DataGrid grid, DataGridColumn activeColumn, bool descending)
{
if (grid == null) return;
foreach (DataGridColumn column in grid.Columns)
{
var columnName = GetColumnName(column);
column.Header = column == activeColumn
? columnName + (descending ? " ▼" : " ▲")
: columnName;
}
}
private static void ClearSortIndicators(DataGrid grid)
{
if (grid == null) return;
foreach (DataGridColumn column in grid.Columns)
column.Header = GetColumnName(column);
}
private static void ApplyCurrentSortIndicator(DataGrid grid, string sortColumn, bool descending)
{
ClearSortIndicators(grid);
if (grid == null || String.IsNullOrWhiteSpace(sortColumn)) return;
foreach (DataGridColumn column in grid.Columns)
{
if (String.Equals(GetColumnName(column), sortColumn, StringComparison.OrdinalIgnoreCase))
{
SetSortIndicator(grid, column, descending);
return;
}
}
}
private static string GetText(IDictionary<string, object> dataContext, string key)
{
object value;
return dataContext.TryGetValue(key, out value) && value != null ? Convert.ToString(value) : "";
}
private static int GetInteger(IDictionary<string, object> dataContext, string key, int defaultValue)
{
object value;
if (!dataContext.TryGetValue(key, out value) || value == null)
return defaultValue;
try { return Convert.ToInt32(value); }
catch { return defaultValue; }
}
private static long GetLong(IDictionary<string, object> dataContext, string key, long defaultValue)
{
object value;
if (!dataContext.TryGetValue(key, out value) || value == null)
return defaultValue;
try { return Convert.ToInt64(value); }
catch { return defaultValue; }
}
private static Dictionary<string, long> GetRowCountCache(IDictionary<string, object> dataContext)
{
object value;
var cache = dataContext.TryGetValue("rowCountCache", out value)
? value as Dictionary<string, long>
: null;
if (cache != null) return cache;
cache = new Dictionary<string, long>(StringComparer.OrdinalIgnoreCase);
dataContext["rowCountCache"] = cache;
return cache;
}
private static bool GetBoolean(IDictionary<string, object> dataContext, string key)
{
object value;
if (!dataContext.TryGetValue(key, out value) || value == null) return false;
try { return Convert.ToBoolean(value); }
catch { return false; }
}
private static void SetObjectList(Window win, IDictionary<string, object> dataContext, DataTable table)
{
dataContext["objectList"] = table;
var list = win.FindName("ObjectList") as ListBox;
if (list != null) list.ItemsSource = table.DefaultView;
}
private static void SetResultGrid(Window win, IDictionary<string, object> dataContext, DataTable table)
{
dataContext["fullQueryResult"] = table;
dataContext["queryResult"] = table;
var schemaKey = GetResultSchemaKey(table);
var schemaChanged = !String.Equals(GetText(dataContext, "resultSchemaKey"), schemaKey, StringComparison.Ordinal);
dataContext["resultSchemaKey"] = schemaKey;
var grid = win.FindName("ResultGrid") as DataGrid;
if (grid != null)
{
if (schemaChanged)
{
grid.ItemsSource = null;
grid.Columns.Clear();
}
grid.ItemsSource = table.DefaultView;
}
}
private static string GetResultSchemaKey(DataTable table)
{
if (table == null || table.Columns.Count == 0) return "";
var parts = new string[table.Columns.Count];
foreach (DataColumn column in table.Columns)
{
var typeName = column.DataType == null ? "" : column.DataType.FullName;
parts[column.Ordinal] = column.ColumnName + "\u001f" + typeName;
}
return String.Join("\u001e", parts);
}
private static string GetResultCellPreview(string value)
{
if (String.IsNullOrEmpty(value) || value.Length <= ResultCellPreviewLength)
return value;
return value.Substring(0, ResultCellPreviewLength) + "...";
}
private static DataTable GetFullQueryResult(IDictionary<string, object> dataContext)
{
object value;
return dataContext.TryGetValue("fullQueryResult", out value) ? value as DataTable : null;
}
private static DataColumn FindDataColumn(DataTable table, string columnName)
{
if (table == null || String.IsNullOrWhiteSpace(columnName)) return null;
foreach (DataColumn column in table.Columns)
{
if (String.Equals(column.ColumnName, columnName, StringComparison.OrdinalIgnoreCase))
return column;
}
return null;
}
private static void ShowCellValue(Window win, IDictionary<string, object> dataContext, DataRowView row, DataGridColumn column)
{
if (row == null || row.Row == null || column == null) return;
var columnName = column.SortMemberPath;
if (String.IsNullOrWhiteSpace(columnName))
columnName = Convert.ToString(column.Header);
var displayedColumn = FindDataColumn(row.Row.Table, columnName);
if (displayedColumn == null)
{
SetStatus(win, dataContext, "无法识别单击单元格的列名");
return;
}
var sourceValue = row.Row[displayedColumn];
var displayedTable = row.Row.Table;
var rowIndex = displayedTable.Rows.IndexOf(row.Row);
var fullTable = GetFullQueryResult(dataContext);
var fullColumn = FindDataColumn(fullTable, displayedColumn.ColumnName);
if (fullTable != null && rowIndex >= 0 && rowIndex < fullTable.Rows.Count && fullColumn != null)
sourceValue = fullTable.Rows[rowIndex][fullColumn];
var value = FormatCellValue(sourceValue);
SetCellValue(win, dataContext, "列:" + displayedColumn.ColumnName, value, true);
SetStatus(win, dataContext, "已显示 " + displayedColumn.ColumnName + " 的完整值");
}
private static void CopyCurrentCell(Window win, IDictionary<string, object> dataContext)
{
if (!GetBoolean(dataContext, "hasCurrentCell"))
{
SetStatus(win, dataContext, "请先单击表格中的一个单元格");
return;
}
try
{
Clipboard.SetText(GetText(dataContext, "currentCellValue"));
SetStatus(win, dataContext, "已复制当前数据项");
}
catch (Exception ex)
{
SetStatus(win, dataContext, "复制失败:" + ex.Message);
}
}
private static string FormatCellValue(object value)
{
if (value == null || value == DBNull.Value) return "NULL";
var bytes = value as byte[];
if (bytes != null) return Convert.ToBase64String(bytes);
return FormatJsonIfPossible(Convert.ToString(value));
}
private static string FormatJsonIfPossible(string value)
{
if (String.IsNullOrWhiteSpace(value)) return value;
var text = value.Trim();
if (!((text.StartsWith("{") && text.EndsWith("}")) || (text.StartsWith("[") && text.EndsWith("]"))))
return value;
try { return JToken.Parse(text).ToString(Formatting.Indented); }
catch (JsonReaderException) { return value; }
}
private static void SetCellValue(Window win, IDictionary<string, object> dataContext, string caption, string value, bool hasValue)
{
dataContext["currentCellCaption"] = caption;
dataContext["currentCellValue"] = value;
dataContext["hasCurrentCell"] = hasValue;
var captionText = win.FindName("CellCaptionText") as TextBlock;
if (captionText != null) captionText.Text = caption;
var valueBox = win.FindName("CellValueBox") as TextBox;
if (valueBox != null) valueBox.Text = value;
}
private static void SetSqlText(Window win, IDictionary<string, object> dataContext, string sql)
{
dataContext["sql"] = sql;
var sqlBox = win.FindName("SqlBox") as TextBox;
if (sqlBox != null) sqlBox.Text = sql;
}
private static void SetCurrentObject(Window win, IDictionary<string, object> dataContext, string text)
{
var label = win.FindName("CurrentObjectText") as TextBlock;
if (label != null) label.Text = text;
}
private static void SetPageText(Window win, int offset, int pageSize, int rowCount, long totalRowCount)
{
var label = win.FindName("PageText") as TextBlock;
if (label == null) return;
var pageNumber = offset / Math.Max(1, pageSize) + 1;
var totalText = totalRowCount >= 0 ? ",共 " + totalRowCount + " 行" : ",总行数未知";
if (rowCount == 0)
{
label.Text = "第 " + pageNumber + " 页,0 行" + totalText;
return;
}
label.Text = "第 " + pageNumber + " 页,第 " + (offset + 1) + " - " + (offset + rowCount) + " 行" + totalText;
}
private static void SetStatus(Window win, IDictionary<string, object> dataContext, string status)
{
dataContext["status"] = status;
var label = win.FindName("StatusText") as TextBlock;
if (label != null) label.Text = status;
}
}找ai写的仅依赖quicker自带的System.Data.SQLite.dll来达到同样的效果,放进自定义窗口辅助C#代码里替换就行
啊??2.0自带了这些模块了吧,这是2.0自带的和sqlite相关的模块
你不会用的是1.45吧?