You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Connected.Components/Components/DataGrid/Cell.cs

168 lines
4.7 KiB

2 years ago
// Copyright (c) MudBlazor 2021
// MudBlazor licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using Connected.Utilities;
namespace Connected.Components;
[RequiresUnreferencedCode(CodeMessage.SerializationUnreferencedCodeMessage)]
internal class Cell<T>
{
private readonly DataGrid<T> _dataGrid;
private readonly Column<T> _column;
internal T _item;
internal string valueString;
internal double? valueNumber;
internal bool isEditing;
internal CellContext<T> cellContext;
#region Computed Properties
internal object ComputedValue
{
get
{
if (_item == null || _column.Field == null)
return null;
// Handle case where T is IDictionary.
if (typeof(T) == typeof(IDictionary<string, object>))
{
if (_column.FieldType == null)
throw new ArgumentNullException(nameof(_column.FieldType));
if (_column.FieldType.IsEnum)
{
var o = ((IDictionary<string, object>)_item)[_column.Field];
if (o == null)
return null;
if (o.GetType() == typeof(JsonElement))
{
var json = (JsonElement)o;
return Enum.ToObject(_column.FieldType, json.GetInt32());
}
else
{
return Enum.ToObject(_column.FieldType, o);
}
}
return ((IDictionary<string, object>)_item)[_column.Field];
}
var property = _item.GetType().GetProperties().SingleOrDefault(x => x.Name == _column.Field);
return property.GetValue(_item);
}
}
internal string computedClass
{
get
{
return new CssBuilder(_column.CellClassFunc?.Invoke(_item))
.AddClass(_column.CellClass)
.AddClass("mud-table-cell")
.AddClass("mud-table-cell-hide", _column.HideSmall)
.AddClass("sticky-left", _column.StickyLeft)
.AddClass("sticky-right", _column.StickyRight)
.AddClass($"edit-mode-cell", _dataGrid.EditMode == DataGridEditMode.Cell && _column.IsEditable)
.Build();
}
}
internal string computedStyle
{
get
{
return new StyleBuilder()
.AddStyle(_column.CellStyleFunc?.Invoke(_item))
.AddStyle(_column.CellStyle)
.Build();
}
}
#endregion
public Cell(DataGrid<T> dataGrid, Column<T> column, T item)
{
_dataGrid = dataGrid;
_column = column;
_item = item;
OnStartedEditingItem();
// Create the CellContext
cellContext = new CellContext<T>(_dataGrid, _item);
}
public async Task StringValueChangedAsync(string value)
{
var property = _item.GetType().GetProperties().SingleOrDefault(x => x.Name == _column.Field);
property.SetValue(_item, value);
// If the edit mode is Cell, we update immediately.
if (_dataGrid.EditMode == DataGridEditMode.Cell)
await _dataGrid.CommitItemChangesAsync(_item);
}
public async Task NumberValueChangedAsync(double? value)
{
var property = _item.GetType().GetProperties().SingleOrDefault(x => x.Name == _column.Field);
property.SetValue(_item, ChangeType(value, property.PropertyType));
// If the edit mode is Cell, we update immediately.
if (_dataGrid.EditMode == DataGridEditMode.Cell)
await _dataGrid.CommitItemChangesAsync(_item);
}
private void OnStartedEditingItem()
{
if (ComputedValue != null)
{
if (ComputedValue.GetType() == typeof(JsonElement))
{
if (_column.dataType == typeof(string))
{
valueString = ((JsonElement)ComputedValue).GetString();
}
else if (_column.isNumber)
{
valueNumber = ((JsonElement)ComputedValue).GetDouble();
}
}
else
{
if (_column.dataType == typeof(string))
{
valueString = (string)ComputedValue;
}
else if (_column.isNumber)
{
valueNumber = Convert.ToDouble(ComputedValue);
}
}
}
}
private object ChangeType(object value, Type conversion)
{
var t = conversion;
if (t.IsGenericType && t.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
{
if (value == null)
{
return null;
}
t = Nullable.GetUnderlyingType(t);
}
return Convert.ChangeType(value, t);
}
}