using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Media; using static Ramitta.winDataGrid; namespace Ramitta { public partial class winDataGrid : UserControl, INotifyPropertyChanged { public DataGrid DataGridControl => xDataGrid; public ObservableCollection< Dictionary > Rows { get; private set; } public Dictionary 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"); 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 AddRow(){ var keys = ColumnsName.Keys.ToList(); var row = new Dictionary { }; 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 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 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()); } } }