diff --git a/Elwig/Helpers/ControlUtils.cs b/Elwig/Helpers/ControlUtils.cs index 1327fe8..d0b075a 100644 --- a/Elwig/Helpers/ControlUtils.cs +++ b/Elwig/Helpers/ControlUtils.cs @@ -217,19 +217,19 @@ namespace Elwig.Helpers { SelectCheckComboBoxItems(ccb, getId, items?.Select(i => getId(i))); } - public static object? GetInputValue(Control input) { + public static int GetInputHashCode(Control input) { if (input is TextBox tb) { - return tb.Text; + return Utils.GetEntityIdentifier(tb.Text); } else if (input is ComboBox sb) { - return sb.SelectedItem; + return Utils.GetEntityIdentifier(sb.SelectedItem); } else if (input is Xceed.Wpf.Toolkit.CheckComboBox ccb) { - return ccb.SelectedItems.Cast().ToArray(); + return Utils.GetEntityIdentifier(ccb.SelectedItems); } else if (input is CheckBox cb) { - return cb.IsChecked?.ToString(); + return Utils.GetEntityIdentifier(cb.IsChecked); } else if (input is RadioButton rb) { - return rb.IsChecked?.ToString(); + return Utils.GetEntityIdentifier(rb.IsChecked); } else { - return null; + return 0; } } } diff --git a/Elwig/Helpers/Utils.cs b/Elwig/Helpers/Utils.cs index 1071f54..10aa6c0 100644 --- a/Elwig/Helpers/Utils.cs +++ b/Elwig/Helpers/Utils.cs @@ -18,7 +18,9 @@ using System.Text.Json.Nodes; using System.IO; using MailKit.Net.Smtp; using MailKit.Security; -using OpenTK.Compute.OpenCL; +using Microsoft.EntityFrameworkCore; +using System.Reflection; +using System.Collections; namespace Elwig.Helpers { public static partial class Utils { @@ -432,5 +434,19 @@ namespace Elwig.Helpers { await client.AuthenticateAsync(username, password); return client; } + + public static int GetEntityIdentifier(object? obj) { + if (obj == null) { + return 0; + } else if (obj is IEnumerable list) { + var arr = list.Cast().Select(o => GetEntityIdentifier(o)).ToArray(); + return ((IStructuralEquatable)arr).GetHashCode(EqualityComparer.Default); + } else if (obj.GetType().GetCustomAttribute(typeof(PrimaryKeyAttribute), false) is not PrimaryKeyAttribute pkAttr) { + return obj.GetHashCode(); + } else { + var pk = pkAttr.PropertyNames.Select(name => obj.GetType().GetProperty(name)!.GetValue(obj)?.GetHashCode() ?? 0).ToArray(); + return ((IStructuralEquatable)pk).GetHashCode(EqualityComparer.Default); + } + } } } diff --git a/Elwig/Windows/AdministrationWindow.cs b/Elwig/Windows/AdministrationWindow.cs index 730c4e5..b8525f2 100644 --- a/Elwig/Windows/AdministrationWindow.cs +++ b/Elwig/Windows/AdministrationWindow.cs @@ -45,8 +45,8 @@ namespace Elwig.Windows { private CheckBox[] CheckBoxInputs; private RadioButton[] RadioButtonInputs; private readonly Dictionary Valid; - private readonly Dictionary OriginalValues; - private readonly Dictionary DefaultValues; + private readonly Dictionary OriginalValues; + private readonly Dictionary DefaultValues; public AdministrationWindow() : base() { IsEditing = false; @@ -198,20 +198,20 @@ namespace Elwig.Windows { protected void FillOriginalValues() { foreach (var tb in TextBoxInputs) - OriginalValues[tb] = tb.Text; + OriginalValues[tb] = Utils.GetEntityIdentifier(tb.Text); foreach (var cb in ComboBoxInputs) - OriginalValues[cb] = cb.SelectedItem; + OriginalValues[cb] = Utils.GetEntityIdentifier(cb.SelectedItem); foreach (var ccb in CheckComboBoxInputs) - OriginalValues[ccb] = ccb.SelectedItems.Cast().ToArray(); + OriginalValues[ccb] = Utils.GetEntityIdentifier(ccb.SelectedItems); foreach (var cb in CheckBoxInputs) - OriginalValues[cb] = cb.IsChecked?.ToString(); + OriginalValues[cb] = Utils.GetEntityIdentifier(cb.IsChecked); foreach (var rb in RadioButtonInputs) - OriginalValues[rb] = rb.IsChecked?.ToString(); + OriginalValues[rb] = Utils.GetEntityIdentifier(rb.IsChecked); } protected void SetOriginalValue(Control input, object? value) { if (input is UnitTextBox utbx) input = utbx.TextBox; - OriginalValues[input] = value is bool b ? b.ToString() : value; + OriginalValues[input] = Utils.GetEntityIdentifier(value); if (InputHasChanged(input)) { ControlUtils.SetInputChanged(input); } else { @@ -221,7 +221,7 @@ namespace Elwig.Windows { protected void SetOriginalValue(Control input) { if (input is UnitTextBox utbx) input = utbx.TextBox; - SetOriginalValue(input, ControlUtils.GetInputValue(input)); + SetOriginalValue(input, ControlUtils.GetInputHashCode(input)); } protected void UnsetOriginalValue(Control input) { @@ -232,7 +232,7 @@ namespace Elwig.Windows { protected void SetDefaultValue(Control input, object? value) { if (input is UnitTextBox utbx) input = utbx.TextBox; - DefaultValues[input] = value is bool b ? b.ToString() : value; + DefaultValues[input] = value != null ? Utils.GetEntityIdentifier(value) : null; if (!InputHasChanged(input)) { if (InputIsNotDefault(input)) { ControlUtils.SetInputNotDefault(input); @@ -244,7 +244,7 @@ namespace Elwig.Windows { protected void SetDefaultValue(Control input) { if (input is UnitTextBox utbx) input = utbx.TextBox; - SetDefaultValue(input, ControlUtils.GetInputValue(input)); + SetDefaultValue(input, ControlUtils.GetInputHashCode(input)); } protected void UnsetDefaultValue(Control input) { @@ -281,15 +281,15 @@ namespace Elwig.Windows { if (!OriginalValues.ContainsKey(input)) { return false; } else if (input is TextBox tb) { - return OriginalValues[tb]?.ToString() != tb.Text; + return OriginalValues[tb] != Utils.GetEntityIdentifier(tb.Text); } else if (input is ComboBox sb) { - return OriginalValues[sb] != sb.SelectedItem; + return OriginalValues[sb] != Utils.GetEntityIdentifier(sb.SelectedItem); } else if (input is CheckComboBox ccb) { - return !ccb.SelectedItems.Cast().ToArray().SequenceEqual(((object[]?)OriginalValues[ccb]) ?? []); + return OriginalValues[ccb] != Utils.GetEntityIdentifier(ccb.SelectedItems); } else if (input is CheckBox cb) { - return (string?)OriginalValues[cb] != cb.IsChecked?.ToString(); + return OriginalValues[cb] != Utils.GetEntityIdentifier(cb.IsChecked); } else if (input is RadioButton rb) { - return (string?)OriginalValues[rb] != rb.IsChecked?.ToString(); + return OriginalValues[rb] != Utils.GetEntityIdentifier(rb.IsChecked); } else { return false; } @@ -300,15 +300,15 @@ namespace Elwig.Windows { if (!DefaultValues.ContainsKey(input)) { return false; } else if (input is TextBox tb) { - return DefaultValues[tb]?.ToString() != tb.Text; + return DefaultValues[tb] != Utils.GetEntityIdentifier(tb.Text); } else if (input is ComboBox sb) { - return DefaultValues[sb] != sb.SelectedItem; + return DefaultValues[sb] != Utils.GetEntityIdentifier(sb.SelectedItem); } else if (input is CheckComboBox ccb) { - return !ccb.SelectedItems.Cast().ToArray().SequenceEqual(((object[]?)DefaultValues[ccb]) ?? []); + return DefaultValues[ccb] != Utils.GetEntityIdentifier(ccb.SelectedItems); } else if (input is CheckBox cb) { - return (string?)DefaultValues[cb] != cb.IsChecked?.ToString(); + return DefaultValues[cb] != Utils.GetEntityIdentifier(cb.IsChecked); } else if (input is RadioButton rb) { - return (string?)DefaultValues[rb] != rb.IsChecked?.ToString(); + return DefaultValues[rb] != Utils.GetEntityIdentifier(rb.IsChecked); } else { return false; }