357 lines
14 KiB
C#
357 lines
14 KiB
C#
using Newtonsoft.Json.Linq;
|
||
using System.Collections.ObjectModel;
|
||
using System.ComponentModel;
|
||
using System.Windows;
|
||
using System.Windows.Controls;
|
||
using System.Windows.Data;
|
||
using System.Windows.Media;
|
||
|
||
namespace Ramitta
|
||
{
|
||
public partial class winDataGrid : UserControl, INotifyPropertyChanged
|
||
{
|
||
public DataGrid DataGridControl => xDataGrid;
|
||
|
||
public ObservableCollection<
|
||
Dictionary<string, object>
|
||
> Rows
|
||
{ get; private set; }
|
||
|
||
public Dictionary<string, object> ColumnsName = new();
|
||
|
||
public winDataGrid()
|
||
{
|
||
InitializeComponent();
|
||
Rows = new();
|
||
xDataGrid.ItemsSource = Rows;
|
||
}
|
||
// 定义列类型的枚举
|
||
public enum ColumnType
|
||
{
|
||
Button,
|
||
CheckBox,
|
||
ComboBox,
|
||
TextBox,
|
||
Label
|
||
}
|
||
public void InitColumns(params (string columnName, ColumnType columnType)[] columns)
|
||
{
|
||
// 循环添加列
|
||
foreach (var column in columns)
|
||
{
|
||
AddColumn(column.columnName, column.columnType);
|
||
}
|
||
}
|
||
|
||
private void SetBindingToProperty(FrameworkElementFactory elementFactory, DependencyProperty property, string path)
|
||
{
|
||
elementFactory.SetValue(property,
|
||
new Binding(path)
|
||
{
|
||
Mode = BindingMode.TwoWay,
|
||
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
|
||
});
|
||
}
|
||
|
||
public void AddColumn(string columnName, ColumnType columnType)
|
||
{
|
||
DataGridTemplateColumn column = new DataGridTemplateColumn();
|
||
FrameworkElementFactory? elementFactory = null;
|
||
ColumnsName.Add(columnName, columnType);
|
||
|
||
switch (columnType)
|
||
{
|
||
case ColumnType.Button:
|
||
elementFactory = new FrameworkElementFactory(typeof(Button));
|
||
SetBindingToProperty(elementFactory, Button.ContentProperty, $"[{columnName}].Content");
|
||
SetBindingToProperty(elementFactory, Button.CommandProperty, $"[{columnName}].Command");
|
||
break;
|
||
case ColumnType.CheckBox:
|
||
elementFactory = new FrameworkElementFactory(typeof(CheckBox));
|
||
SetBindingToProperty(elementFactory, CheckBox.IsCheckedProperty, $"[{columnName}].IsChecked");
|
||
break;
|
||
case ColumnType.ComboBox:
|
||
elementFactory = new FrameworkElementFactory(typeof(ComboBox));
|
||
elementFactory.SetValue(ComboBox.SelectedIndexProperty, 0);
|
||
SetBindingToProperty(elementFactory, ComboBox.ItemsSourceProperty, $"[{columnName}].ItemsSource");
|
||
SetBindingToProperty(elementFactory, ComboBox.SelectedValueProperty, $"[{columnName}].SelectedValue");
|
||
SetBindingToProperty(elementFactory, ComboBox.MaxWidthProperty, $"[{columnName}].MaxWidth");
|
||
break;
|
||
case ColumnType.Label:
|
||
elementFactory = new FrameworkElementFactory(typeof(Label));
|
||
SetBindingToProperty(elementFactory, Label.ContentProperty, $"[{columnName}].Content");
|
||
SetBindingToProperty(elementFactory, Label.BackgroundProperty, $"[{columnName}].Background");
|
||
break;
|
||
case ColumnType.TextBox:
|
||
elementFactory = new FrameworkElementFactory(typeof(TextBox));
|
||
SetBindingToProperty(elementFactory, TextBox.TextProperty, $"[{columnName}].Text");
|
||
SetBindingToProperty(elementFactory, TextBox.BackgroundProperty, $"[{columnName}].Background");
|
||
break;
|
||
}
|
||
DataTemplate dataTemplate = new DataTemplate() { VisualTree = elementFactory };
|
||
|
||
column.Header = columnName;
|
||
column.CellTemplate = dataTemplate;
|
||
column.CellEditingTemplate = dataTemplate;
|
||
xDataGrid.Columns.Add(column);
|
||
}
|
||
public Dictionary<string, object> AddRow()
|
||
{
|
||
var keys = ColumnsName.Keys.ToList();
|
||
var row = new Dictionary<string, object> { };
|
||
|
||
foreach (var key in keys)
|
||
{
|
||
|
||
switch (ColumnsName[key])
|
||
{
|
||
case ColumnType.Button:
|
||
row.Add(key, new Button());
|
||
break;
|
||
case ColumnType.CheckBox:
|
||
row.Add(key, new CheckBox());
|
||
break;
|
||
case ColumnType.ComboBox:
|
||
row.Add(key, new ComboBox());
|
||
break;
|
||
case ColumnType.TextBox:
|
||
row.Add(key, new TextBox());
|
||
break;
|
||
case ColumnType.Label:
|
||
row.Add(key, new Label());
|
||
break;
|
||
}
|
||
}
|
||
|
||
Rows.Add(row);
|
||
return row;
|
||
}
|
||
|
||
public void Clear()
|
||
{
|
||
Rows.Clear();
|
||
}
|
||
|
||
public int Count()
|
||
{
|
||
return Rows.Count();
|
||
}
|
||
|
||
public void RemoveRow(Dictionary<string, object> row)
|
||
{
|
||
// 从 Rows 集合中移除指定的行
|
||
if (Rows.Contains(row))
|
||
{
|
||
Rows.Remove(row);
|
||
}
|
||
}
|
||
|
||
public event PropertyChangedEventHandler? PropertyChanged;
|
||
protected void OnPropertyChanged(string propertyName)
|
||
{
|
||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||
}
|
||
|
||
|
||
|
||
public JObject JsonPrint()
|
||
{
|
||
JObject result = new JObject();
|
||
JArray rowsArray = new JArray();
|
||
|
||
// 遍历所有行
|
||
foreach (var row in Rows)
|
||
{
|
||
JObject rowObject = new JObject();
|
||
|
||
// 遍历行中的所有列
|
||
foreach (var column in row)
|
||
{
|
||
string columnName = column.Key;
|
||
object value = column.Value;
|
||
|
||
// 根据控件类型序列化不同的属性
|
||
switch (ColumnsName[columnName])
|
||
{
|
||
case ColumnType.Button:
|
||
if (value is Button button)
|
||
rowObject[columnName] = button.Content?.ToString() ?? "";
|
||
break;
|
||
|
||
case ColumnType.CheckBox:
|
||
if (value is CheckBox checkBox)
|
||
rowObject[columnName] = checkBox.IsChecked ?? false;
|
||
break;
|
||
|
||
case ColumnType.ComboBox:
|
||
if (value is ComboBox comboBox)
|
||
{
|
||
JObject comboObj = new JObject
|
||
{
|
||
["SelectedValue"] = comboBox.SelectedValue?.ToString(),
|
||
["SelectedIndex"] = comboBox.SelectedIndex,
|
||
["ItemsCount"] = comboBox.Items?.Count ?? 0
|
||
};
|
||
rowObject[columnName] = comboObj;
|
||
}
|
||
break;
|
||
|
||
case ColumnType.TextBox:
|
||
if (value is TextBox textBox)
|
||
{
|
||
JObject textBoxObj = new JObject
|
||
{
|
||
["Text"] = textBox.Text,
|
||
["Background"] = textBox.Background?.ToString()
|
||
};
|
||
rowObject[columnName] = textBoxObj;
|
||
}
|
||
break;
|
||
|
||
case ColumnType.Label:
|
||
if (value is Label label)
|
||
{
|
||
JObject labelObj = new JObject
|
||
{
|
||
["Content"] = label.Content?.ToString(),
|
||
["Background"] = label.Background?.ToString()
|
||
};
|
||
rowObject[columnName] = labelObj;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
rowsArray.Add(rowObject);
|
||
}
|
||
|
||
// 添加列信息
|
||
JObject columnsInfo = new JObject();
|
||
foreach (var column in ColumnsName)
|
||
{
|
||
columnsInfo[column.Key] = column.Value.ToString();
|
||
}
|
||
|
||
result["Columns"] = columnsInfo;
|
||
result["Rows"] = rowsArray;
|
||
|
||
return result;
|
||
}
|
||
|
||
public void JsonLoad(string jsonString)
|
||
{
|
||
try
|
||
{
|
||
JObject jsonData = JObject.Parse(jsonString);
|
||
|
||
// 清空现有数据
|
||
Clear();
|
||
xDataGrid.Columns.Clear();
|
||
ColumnsName.Clear();
|
||
|
||
// 加载列信息
|
||
JObject columnsInfo = (JObject)jsonData["Columns"];
|
||
foreach (var column in columnsInfo.Properties())
|
||
{
|
||
string columnName = column.Name;
|
||
ColumnType columnType = (ColumnType)Enum.Parse(typeof(ColumnType), column.Value.ToString());
|
||
ColumnsName.Add(columnName, columnType);
|
||
AddColumn(columnName, columnType);
|
||
}
|
||
|
||
// 加载行数据
|
||
JArray rowsArray = (JArray)jsonData["Rows"];
|
||
foreach (JObject rowObject in rowsArray)
|
||
{
|
||
Dictionary<string, object> newRow = AddRow();
|
||
|
||
foreach (var property in rowObject.Properties())
|
||
{
|
||
string columnName = property.Name;
|
||
JToken value = property.Value;
|
||
|
||
if (newRow.ContainsKey(columnName) && ColumnsName.ContainsKey(columnName))
|
||
{
|
||
object control = newRow[columnName];
|
||
|
||
switch (ColumnsName[columnName])
|
||
{
|
||
case ColumnType.Button:
|
||
if (control is Button button)
|
||
button.Content = value.ToString();
|
||
break;
|
||
|
||
case ColumnType.CheckBox:
|
||
if (control is CheckBox checkBox)
|
||
checkBox.IsChecked = (bool)value;
|
||
break;
|
||
|
||
case ColumnType.ComboBox:
|
||
if (control is ComboBox comboBox && value is JObject comboObj)
|
||
{
|
||
comboBox.SelectedValue = comboObj["SelectedValue"]?.ToString();
|
||
comboBox.SelectedIndex = (int)comboObj["SelectedIndex"];
|
||
// 注意:ItemsSource 需要额外处理,这里只恢复选中状态
|
||
}
|
||
break;
|
||
|
||
case ColumnType.TextBox:
|
||
if (control is TextBox textBox && value is JObject textBoxObj)
|
||
{
|
||
textBox.Text = textBoxObj["Text"]?.ToString();
|
||
if (textBoxObj["Background"] != null)
|
||
{
|
||
try
|
||
{
|
||
var converter = new BrushConverter();
|
||
textBox.Background = (Brush)converter.ConvertFromString(textBoxObj["Background"].ToString());
|
||
}
|
||
catch
|
||
{
|
||
textBox.Background = Brushes.Transparent;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
case ColumnType.Label:
|
||
if (control is Label label && value is JObject labelObj)
|
||
{
|
||
label.Content = labelObj["Content"]?.ToString();
|
||
if (labelObj["Background"] != null)
|
||
{
|
||
try
|
||
{
|
||
var converter = new BrushConverter();
|
||
label.Background = (Brush)converter.ConvertFromString(labelObj["Background"].ToString());
|
||
}
|
||
catch
|
||
{
|
||
label.Background = Brushes.Transparent;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 刷新显示
|
||
xDataGrid.Items.Refresh();
|
||
OnPropertyChanged(nameof(Rows));
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show($"加载JSON数据时出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||
}
|
||
}
|
||
|
||
// 重载方法,支持直接从 JObject 加载
|
||
public void JsonLoad(JObject jsonData)
|
||
{
|
||
JsonLoad(jsonData.ToString());
|
||
}
|
||
}
|
||
}
|