예제 #1
0
 public MementoManager(IMForm mainForm)
 {
     // Creates new MementoManager with blank stacks and assigned main form reference
     _undoStack = new Stack <Memento>();
     _redoStack = new Stack <Memento>();
     _mainForm  = mainForm;
 }
        public void RefreshMementoMenus()
        {
            // Should update undo / redo menus in form's menu strip
            try
            {
                IMForm         child   = (IMForm)ActiveMdiChild;
                MementoManager manager = child.GetMementoManager();

                if (manager.hasUndo())
                {
                    undoMenuItem.Enabled = true;
                    undoMenuItem.Text    = "Undo " + manager.GetUndoDesc();
                }
                else
                {
                    undoMenuItem.Enabled = false;
                    undoMenuItem.Text    = "Undo";
                }

                if (manager.hasRedo())
                {
                    redoMenuItem.Enabled = true;
                    redoMenuItem.Text    = "Redo " + manager.GetRedoDesc();
                }
                else
                {
                    redoMenuItem.Enabled = false;
                    redoMenuItem.Text    = "Redo";
                }
            }
            catch (NullReferenceException)
            {
                // No active child yet; menus should be disabled
                undoMenuItem.Enabled = false;
                undoMenuItem.Text    = "Undo";
                redoMenuItem.Enabled = false;
                redoMenuItem.Text    = "Redo";
            }
            catch (InvalidCastException)
            {
                // Active Mdi Child is not an IMForm; disable menus
                undoMenuItem.Enabled = false;
                undoMenuItem.Text    = "Undo";
                redoMenuItem.Enabled = false;
                redoMenuItem.Text    = "Redo";
            }
        }
 private void redoMenuItem_Click(object sender, EventArgs e)
 {
     try
     {
         IMForm         child   = (IMForm)ActiveMdiChild;
         MementoManager manager = child.GetMementoManager();
         manager.Redo();
         child.RefreshValues();
     }
     catch (NullReferenceException)
     {
         // There is no child form yet
     }
     catch (InvalidCastException)
     {
         // Mdi child is not an IMForm
     }
 }
예제 #4
0
        private static async Task InvokeValueChanged(IMForm pParent, IMPropertyInfo pPropertyInfo, IMField pField, object pModel, object pNewValue)
        {
            lock (pModel)
            {
                if (pPropertyInfo.GetCustomAttribute <DateAttribute>() != null)
                {
                    var dateTime = pNewValue as DateTime?;

                    if (dateTime != null && dateTime.Value.Kind == DateTimeKind.Unspecified)
                    {
                        pNewValue = DateTime.SpecifyKind(dateTime.Value, DateTimeKind.Utc);
                    }
                }

                pPropertyInfo.SetValue(pModel, pNewValue);
            }

            await pParent.OnInputValueChanged(pField, pPropertyInfo, pNewValue);
        }
예제 #5
0
        public static void AppendInput <T>(RenderTreeBuilder pBuilder, IMPropertyInfo pPropertyInfo, object pModel, Guid pId, IMForm pParent, bool pIsInFilterRow, IMField pField)
        {
            try
            {
                if (!IsTypeSupported(typeof(T)) || IsPropertyHolderNull(pPropertyInfo, pModel))
                {
                    ShowNotSupportedType(pBuilder, pPropertyInfo, pModel, pId, pParent);
                    return;
                }

                T    value = (T)(pPropertyInfo.GetValue(pModel) ?? default(T));
                Type tType = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);

                bool isReadOnly = pPropertyInfo.IsReadOnly || pPropertyInfo.GetCustomAttribute(typeof(ReadOnlyAttribute)) != null;

                if (mNumberTypes.Contains(tType))
                {
                    pBuilder.OpenComponent <InputNumber <T> >(0);
                }
                else if (tType == typeof(DateTime) || tType == typeof(DateTimeOffset))
                {
                    if (pPropertyInfo.GetCustomAttribute(typeof(TimeAttribute)) != null)
                    {
                        pBuilder.OpenComponent <InputTime <T> >(0);
                    }
                    else if (pPropertyInfo.GetCustomAttribute(typeof(DateTimeAttribute)) != null)
                    {
                        pBuilder.OpenComponent <InputDateTime <T> >(0);
                    }
                    else
                    {
                        pBuilder.OpenComponent <InputDate <T> >(0);
                    }
                }
                else if (typeof(T) == typeof(bool))
                {
                    pBuilder.OpenComponent <MInputCheckbox>(0);
                }
                else if (typeof(T) == typeof(bool?))
                {
                    pBuilder.OpenComponent <MSelect <T> >(0);
                    if (pIsInFilterRow)
                    {
                        pBuilder.AddAttribute(10, "NullValueDescription", "\u200b");
                    }
                }
                else if (tType == typeof(Guid))
                {
                    pBuilder.OpenComponent <InputGuid <T> >(0);
                }
                else if (tType.IsEnum)
                {
                    pBuilder.OpenComponent <MSelect <T> >(0);
                    if (pIsInFilterRow)
                    {
                        pBuilder.AddAttribute(10, "NullValueDescription", "\u200b");
                    }
                }
                else
                {
                    if (pPropertyInfo.GetCustomAttribute(typeof(TextAreaAttribute)) != null)
                    {
                        pBuilder.OpenComponent <InputTextArea>(0);
                    }
                    else
                    {
                        pBuilder.OpenComponent <InputText>(0);
                    }
                }

                if (pPropertyInfo.GetCustomAttribute(typeof(PasswordAttribute)) != null)
                {
                    pBuilder.AddAttribute(33, "type", "password");
                }

                if (pField.AdditionalAttributes != null)
                {
                    pBuilder.AddMultipleAttributes(17, pField.AdditionalAttributes
                                                   .Where(a => a.Key != Extensions.MFORM_IN_TABLE_ROW_TD_STYLE_ATTRIBUTE)
                                                   .Where(a => a.Key != nameof(IMGridColumn))
                                                   .ToDictionary(a => a.Key, a => a.Value));
                }

                pBuilder.AddAttribute(1, "id", pId);
                pBuilder.AddAttribute(2, "Value", value);

                pBuilder.AddAttribute(23, "ValueChanged", RuntimeHelpers.CreateInferredEventCallback <T>(pParent, async __value =>
                {
                    pPropertyInfo.SetValue(pModel, __value);
                    await pParent.OnInputValueChanged(pField, pPropertyInfo, __value);
                }, value));

                pBuilder.AddAttribute(23, "onkeyup", EventCallback.Factory.Create <KeyboardEventArgs>(pParent, (a) =>
                {
                    pParent.OnInputKeyUp(a);
                }));

                var valueExpression = GetValueExpression <T>(pPropertyInfo, pModel);

                pBuilder.AddAttribute(4, "ValueExpression", valueExpression);

                string cssClass = "m-form-control";

                if (isReadOnly)
                {
                    pBuilder.AddAttribute(33, "disabled", string.Empty);
                    pBuilder.AddAttribute(33, "IsDisabled", true);
                }

                pBuilder.AddAttribute(10, "class", cssClass);

                if (typeof(T) == typeof(bool?))
                {
                    IEnumerable <bool?> options = new bool?[] { true, false };
                    pBuilder.AddAttribute(10, "Options", options);
                }

                pBuilder.CloseComponent();

                if (pParent.EnableValidation)
                {
                    pBuilder.OpenComponent <ValidationMessage <T> >(60);
                    pBuilder.AddAttribute(61, "For", valueExpression);
                    pBuilder.CloseComponent();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                throw;
            }
        }
예제 #6
0
        public static void ShowNotSupportedType(RenderTreeBuilder pBuilder, IMPropertyInfo pPropertyInfo, object pModel, Guid pId, IMForm pParent)
        {
            var value = pPropertyInfo.GetValue(pModel);

            pBuilder.OpenElement(45, "input");
            pBuilder.AddAttribute(1, "id", pId);
            pBuilder.AddAttribute(2, "Value", value);
            pBuilder.AddAttribute(33, "disabled", string.Empty);
            pBuilder.AddAttribute(33, "class", "m-form-control");
            pBuilder.CloseElement();
        }
예제 #7
0
        public static void AppendComplexType <T, TProperty>(RenderTreeBuilder pBuilder, IMPropertyInfo pPropertyInfo, T pModel, Guid pId, IMForm pParent, MComplexPropertyField <T, TProperty> pComplexField,
                                                            MFormGridContext pGridContext)
        {
            if (pComplexField.Template == null)
            {
                ShowNotSupportedType(pBuilder, pPropertyInfo, pModel, pId, pParent);
                return;
            }

            MComplexPropertyFieldContext <TProperty> context = new MComplexPropertyFieldContext <TProperty>();

            TProperty value = (TProperty)pPropertyInfo.GetValue(pModel);

#pragma warning disable BL0005 // Component parameter should not be set outside of its component.
            context.Row              = pModel;
            context.InputId          = pId;
            context.Value            = value;
            context.MFormGridContext = pGridContext;

            context.ValueChanged = RuntimeHelpers.CreateInferredEventCallback <TProperty>(pParent, async __value =>
            {
                pPropertyInfo.SetValue(pModel, __value);
                await pParent.OnInputValueChanged(pComplexField, pPropertyInfo, __value);
            }, value);

            context.ValueExpression = GetValueExpression <TProperty>(pPropertyInfo, pModel);

#pragma warning restore BL0005 // Component parameter should not be set outside of its component.

            pBuilder.AddContent(42, pComplexField.Template?.Invoke(context));
        }
예제 #8
0
        public static void AppendInput <T>(RenderTreeBuilder pBuilder, IMPropertyInfo pPropertyInfo, object pModel, Guid pId, IMForm pParent, bool pIsInFilterRow, IMField pField, bool pUpdateOnInput)
        {
            try
            {
                if (!IsTypeSupported(typeof(T)) || IsPropertyHolderNull(pPropertyInfo, pModel))
                {
                    ShowNotSupportedType(pBuilder, pPropertyInfo, pModel, pId);
                    return;
                }

                T   value = default(T);
                var val   = pPropertyInfo.GetValue(pModel);

                if (val != null)
                {
                    value = (T)ReflectionHelper.ChangeType(val, typeof(T));
                }

                Type tType = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);

                bool isReadOnly = pPropertyInfo.IsReadOnly || pPropertyInfo.GetCustomAttribute <ReadOnlyAttribute>() != null;

                var restrictValues = pPropertyInfo.GetCustomAttribute <RestrictValuesAttribute>();

                if (typeof(T) == typeof(bool?) || tType.IsEnum || restrictValues != null)
                {
                    pBuilder.OpenComponent <MSelect <T> >(0);
                    if (pIsInFilterRow)
                    {
                        pBuilder.AddAttribute(10, "NullValueDescription", "\u200b");
                    }
                }
                else if (mNumberTypes.Contains(tType))
                {
                    if (pUpdateOnInput)
                    {
                        pBuilder.OpenComponent <InputNumberOnInput <T> >(0);
                    }
                    else
                    {
                        pBuilder.OpenComponent <InputNumber <T> >(0);
                    }
                }
                else if (tType == typeof(DateTime) || tType == typeof(DateTimeOffset))
                {
                    if (pPropertyInfo.GetCustomAttribute <TimeAttribute>() != null)
                    {
                        pBuilder.OpenComponent <InputTime <T> >(0);
                    }
                    else if (pPropertyInfo.GetCustomAttribute <DateTimeAttribute>() != null)
                    {
                        pBuilder.OpenComponent <InputDateTime <T> >(0);
                    }
                    else
                    {
                        pBuilder.OpenComponent <InputDate <T> >(0);
                    }
                }
                else if (typeof(T) == typeof(bool))
                {
                    pBuilder.OpenComponent <MInputCheckbox>(0);
                }
                else if (tType == typeof(Guid))
                {
                    pBuilder.OpenComponent <InputGuid <T> >(0);
                }
                else if (tType == typeof(Type))
                {
                    pBuilder.OpenComponent <InputType>(0);
                }
                else
                {
                    if (pPropertyInfo.GetCustomAttribute <TextAreaAttribute>() != null)
                    {
                        pBuilder.OpenComponent <InputTextArea>(0);
                    }
                    else
                    {
                        pBuilder.OpenComponent <InputText>(0);
                    }
                }

                if (pPropertyInfo.GetCustomAttribute <PasswordAttribute>() != null)
                {
                    pBuilder.AddAttribute(33, "type", "password");
                }

                if (pField.AdditionalAttributes != null)
                {
                    pBuilder.AddMultipleAttributes(17, pField.AdditionalAttributes
                                                   .Where(a => a.Key != Extensions.MFORM_IN_TABLE_ROW_TD_STYLE_ATTRIBUTE)
                                                   .Where(a => a.Key != nameof(IMGridColumn))
                                                   .ToDictionary(a => a.Key, a => a.Value));
                }

                //      pBuilder.SetUpdatesAttributeName(pPropertyInfo.Name);

                pBuilder.AddAttribute(1, "id", pId);
                pBuilder.AddAttribute(2, "Value", value);

                pBuilder.AddAttribute(129, "form", pParent.Id);

                pBuilder.AddAttribute(23, "ValueChanged", RuntimeHelpers.CreateInferredEventCallback <T>(pParent, async __value =>
                {
                    await InvokeValueChanged(pParent, pPropertyInfo, pField, pModel, __value);
                }, value));

                if (pUpdateOnInput && !mNumberTypes.Contains(tType))
                {
                    pBuilder.AddAttribute(23, "oninput", EventCallback.Factory.Create <ChangeEventArgs>(pParent, async a =>
                    {
                        object value = a.Value;
                        value        = ReflectionHelper.ChangeType(value, typeof(T)); //maybe the TryParseValueFromString method of the input is better?
                        await InvokeValueChanged(pParent, pPropertyInfo, pField, pModel, value);
                    }));
                }

                pBuilder.AddAttribute(23, "onkeyup", EventCallback.Factory.Create <KeyboardEventArgs>(pParent, (a) =>
                {
                    pParent.OnInputKeyUp(a, pPropertyInfo);
                }));

                var valueExpression = GetValueExpression <T>(pPropertyInfo, pModel);

                pBuilder.AddAttribute(4, "ValueExpression", valueExpression);

                string cssClass = "m-form-control";

                if (isReadOnly)
                {
                    pBuilder.AddAttribute(33, "disabled", string.Empty);
                    pBuilder.AddAttribute(33, "IsDisabled", true);
                }

                pBuilder.AddAttribute(10, "class", cssClass);
                // pBuilder.SetUpdatesAttributeName(pPropertyInfo.Name); <- new code generator will add this, but I don't know why

                if (restrictValues != null)
                {
                    foreach (var allowedValue in restrictValues.AllowedValues)
                    {
                        if (typeof(T) != typeof(string) && !typeof(T).IsAssignableFrom(allowedValue.GetType()))
                        {
                            throw new Exception($"Allowed value {allowedValue} does not implement property type {typeof(T).AssemblyQualifiedName}");
                        }
                    }

                    IEnumerable <T> options;

                    if (typeof(T) == typeof(string))
                    {
                        options = restrictValues.AllowedValues.Select(v => (T)(object)v.ToString()).ToArray();
                    }
                    else
                    {
                        options = restrictValues.AllowedValues.Cast <T>().ToArray();
                    }

                    pBuilder.AddAttribute(10, "Options", options);
                }
                else if (typeof(T) == typeof(bool?))
                {
                    IEnumerable <bool?> options = new bool?[] { true, false };
                    pBuilder.AddAttribute(10, "Options", options);
                }

                pBuilder.CloseComponent();

                if (pParent.EnableValidation)
                {
                    pBuilder.OpenComponent <ValidationMessage <T> >(60);
                    pBuilder.AddAttribute(61, "For", valueExpression);
                    pBuilder.CloseComponent();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                throw;
            }
        }
예제 #9
0
        public static void AppendComplexType <T, TProperty>(RenderTreeBuilder pBuilder, IMPropertyInfo pPropertyInfo, T pModel, Guid pId, IMForm pParent, MComplexPropertyField <TProperty> pComplexField,
                                                            MFormGridContext pGridContext)
        {
            if (pComplexField.Template == null)
            {
                ShowNotSupportedType(pBuilder, pPropertyInfo, pModel, pId);
                return;
            }

            TProperty value = (TProperty)pPropertyInfo.GetValue(pModel);

            var context = new MComplexPropertyFieldContext <TProperty>
            {
                Row              = pModel,
                InputId          = pId.ToString(),
                FormId           = pParent.Id.ToString(),
                Form             = pParent,
                Value            = value,
                MFormGridContext = pGridContext,

                ValueChanged = RuntimeHelpers.CreateInferredEventCallback <TProperty>(pParent, async __value =>
                {
                    pPropertyInfo.SetValue(pModel, __value);
                    await pParent.OnInputValueChanged(pComplexField, pPropertyInfo, __value);
                }, value),

                ValueExpression = GetValueExpression <TProperty>(pPropertyInfo, pModel)
            };

            pBuilder.AddContent(263, pComplexField.Template?.Invoke(context));

            if (pParent.EnableValidation)
            {
                pBuilder.OpenComponent <ValidationMessage <TProperty> >(236);
                pBuilder.AddAttribute(237, "For", context.ValueExpression);
                pBuilder.CloseComponent();
            }
        }
예제 #10
0
 public void RegisterForm(IMForm pForm)
 {
     Forms.Add(pForm);
 }