Files
Ramitta-lib/Ramitta/winDataGrid.xaml.cs

357 lines
14 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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());
}
}
}