405 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			405 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using Elwig.Helpers;
 | 
						|
using Elwig.Models;
 | 
						|
using System;
 | 
						|
using System.Collections.Generic;
 | 
						|
using System.ComponentModel;
 | 
						|
using System.Linq;
 | 
						|
using System.Threading.Tasks;
 | 
						|
using System.Windows;
 | 
						|
using System.Windows.Controls;
 | 
						|
using Xceed.Wpf.Toolkit;
 | 
						|
 | 
						|
namespace Elwig.Windows {
 | 
						|
    public abstract class AdministrationWindow : ContextWindow {
 | 
						|
 | 
						|
        protected Control[] ExemptInputs { private get; set; }
 | 
						|
        protected Control[] RequiredInputs { private get; set; }
 | 
						|
 | 
						|
        private bool _IsEditing;
 | 
						|
        private bool _IsCreating;
 | 
						|
        protected bool IsEditing {
 | 
						|
            get { return _IsEditing; }
 | 
						|
            set {
 | 
						|
                _IsEditing = value;
 | 
						|
                LockContext = IsEditing;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        protected bool IsCreating {
 | 
						|
            get { return _IsCreating; }
 | 
						|
            set {
 | 
						|
                _IsCreating = value;
 | 
						|
                LockContext = IsEditing;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        protected bool IsClosing { get; private set; }
 | 
						|
 | 
						|
        private TextBox[] TextBoxInputs;
 | 
						|
        private TextBox[] PlzInputs;
 | 
						|
        private ComboBox[] ComboBoxInputs;
 | 
						|
        private ComboBox[] PlzOrtInputs;
 | 
						|
        private CheckComboBox[] CheckComboBoxInputs;
 | 
						|
        private CheckBox[] CheckBoxInputs;
 | 
						|
        private RadioButton[] RadioButtonInputs;
 | 
						|
        private readonly Dictionary<Control, bool> Valid;
 | 
						|
        private readonly Dictionary<Control, object?> OriginalValues;
 | 
						|
 | 
						|
        public AdministrationWindow() : base() {
 | 
						|
            IsEditing = false;
 | 
						|
            IsCreating = false;
 | 
						|
            ExemptInputs = Array.Empty<Control>();
 | 
						|
            RequiredInputs = Array.Empty<Control>();
 | 
						|
            TextBoxInputs = Array.Empty<TextBox>();
 | 
						|
            PlzInputs = Array.Empty<TextBox>();
 | 
						|
            ComboBoxInputs = Array.Empty<ComboBox>();
 | 
						|
            CheckComboBoxInputs = Array.Empty<CheckComboBox>();
 | 
						|
            PlzOrtInputs = Array.Empty<ComboBox>();
 | 
						|
            CheckBoxInputs = Array.Empty<CheckBox>();
 | 
						|
            RadioButtonInputs = Array.Empty<RadioButton>();
 | 
						|
            Valid = new();
 | 
						|
            OriginalValues = new();
 | 
						|
            Closing += OnClosing;
 | 
						|
            Loaded += OnLoaded;
 | 
						|
        }
 | 
						|
 | 
						|
        private void OnLoaded(object sender, RoutedEventArgs evt) {
 | 
						|
            TextBoxInputs = Utils.FindAllChildren<TextBox>(this, ExemptInputs).ToArray();
 | 
						|
            ComboBoxInputs = Utils.FindAllChildren<ComboBox>(this, ExemptInputs).ToArray();
 | 
						|
            CheckBoxInputs = Utils.FindAllChildren<CheckBox>(this, ExemptInputs).ToArray();
 | 
						|
            CheckComboBoxInputs = Utils.FindAllChildren<CheckComboBox>(this, ExemptInputs).ToArray();
 | 
						|
            RadioButtonInputs = Utils.FindAllChildren<RadioButton>(this, ExemptInputs).ToArray();
 | 
						|
            PlzInputs = TextBoxInputs.Where(tb => "PLZ".Equals(tb.Tag)).ToArray();
 | 
						|
            PlzOrtInputs = PlzInputs.Select(tb => Utils.FindNextSibling<ComboBox>(tb) ?? throw new MissingMemberException()).ToArray();
 | 
						|
            foreach (var tb in TextBoxInputs)
 | 
						|
                Valid[tb] = true;
 | 
						|
            foreach (var cb in ComboBoxInputs)
 | 
						|
                cb.SelectionChanged += ComboBox_SelectionChanged;
 | 
						|
            foreach (var cb in CheckComboBoxInputs)
 | 
						|
                cb.ItemSelectionChanged += ComboBox_SelectionChanged;
 | 
						|
            ValidateRequiredInputs();
 | 
						|
        }
 | 
						|
 | 
						|
        private void OnClosing(object? sender, CancelEventArgs evt) {
 | 
						|
            IsClosing = true;
 | 
						|
        }
 | 
						|
 | 
						|
        private ComboBox GetPlzOrtInput(TextBox input) {
 | 
						|
            return PlzOrtInputs[Array.IndexOf(PlzInputs, input)];
 | 
						|
        }
 | 
						|
 | 
						|
        abstract protected void UpdateButtons();
 | 
						|
 | 
						|
        protected override async Task RenewContext() {
 | 
						|
            for (int i = 0; i < PlzInputs.Length; i++)
 | 
						|
                UpdatePlz(PlzInputs[i], PlzOrtInputs[i]);
 | 
						|
        }
 | 
						|
 | 
						|
        protected void ValidateInput(Control input, bool valid) {
 | 
						|
            Valid[input] = valid;
 | 
						|
        }
 | 
						|
 | 
						|
        protected bool SenderIsRequired(object sender) {
 | 
						|
            return (sender is Control c) && RequiredInputs.Contains(c);
 | 
						|
        }
 | 
						|
 | 
						|
        protected void ClearInputStates() {
 | 
						|
            foreach (var tb in TextBoxInputs)
 | 
						|
                Utils.ClearInputState(tb);
 | 
						|
            foreach (var cb in ComboBoxInputs)
 | 
						|
                Utils.ClearInputState(cb);
 | 
						|
            foreach (var cb in CheckBoxInputs)
 | 
						|
                Utils.ClearInputState(cb);
 | 
						|
            foreach (var rb in RadioButtonInputs)
 | 
						|
                Utils.ClearInputState(rb);
 | 
						|
        }
 | 
						|
 | 
						|
        protected void ValidateRequiredInputs() {
 | 
						|
            foreach (var input in RequiredInputs) {
 | 
						|
                if (input is TextBox tb && tb.Text.Length == 0) {
 | 
						|
                    Utils.SetInputInvalid(input);
 | 
						|
                    Valid[input] = false;
 | 
						|
                } else if (input is ComboBox cb && cb.SelectedItem == null && cb.ItemsSource != null) {
 | 
						|
                    Utils.SetInputInvalid(input);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        protected void LockInputs() {
 | 
						|
            foreach (var tb in TextBoxInputs)
 | 
						|
                tb.IsReadOnly = true;
 | 
						|
            foreach (var cb in ComboBoxInputs)
 | 
						|
                cb.IsEnabled = false;
 | 
						|
            foreach (var cb in CheckBoxInputs)
 | 
						|
                cb.IsEnabled = false;
 | 
						|
            foreach (var rb in RadioButtonInputs)
 | 
						|
                rb.IsEnabled = false;
 | 
						|
        }
 | 
						|
 | 
						|
        protected void UnlockInputs() {
 | 
						|
            foreach (var tb in TextBoxInputs)
 | 
						|
                tb.IsReadOnly = false;
 | 
						|
            foreach (var cb in ComboBoxInputs)
 | 
						|
                cb.IsEnabled = true;
 | 
						|
            foreach (var cb in CheckBoxInputs)
 | 
						|
                cb.IsEnabled = true;
 | 
						|
            foreach (var rb in RadioButtonInputs)
 | 
						|
                rb.IsEnabled = true;
 | 
						|
        }
 | 
						|
 | 
						|
        protected void ClearOriginalValues() {
 | 
						|
            OriginalValues.Clear();
 | 
						|
        }
 | 
						|
 | 
						|
        protected void FillOriginalValues() {
 | 
						|
            foreach (var tb in TextBoxInputs)
 | 
						|
                OriginalValues[tb] = tb.Text;
 | 
						|
            foreach (var cb in ComboBoxInputs)
 | 
						|
                OriginalValues[cb] = cb.SelectedItem;
 | 
						|
            foreach (var cb in CheckBoxInputs)
 | 
						|
                OriginalValues[cb] = (cb.IsChecked ?? false) ? bool.TrueString : null;
 | 
						|
            foreach (var rb in RadioButtonInputs)
 | 
						|
                OriginalValues[rb] = (rb.IsChecked ?? false) ? bool.TrueString : null;
 | 
						|
        }
 | 
						|
 | 
						|
        protected void SetOriginalValue(Control input, object? value) {
 | 
						|
            OriginalValues[input] = value;
 | 
						|
        }
 | 
						|
 | 
						|
        protected void UnsetOriginalValue(Control input) {
 | 
						|
            OriginalValues.Remove(input);
 | 
						|
        }
 | 
						|
 | 
						|
        protected void ClearInputs() {
 | 
						|
            foreach (var tb in TextBoxInputs)
 | 
						|
                tb.Text = "";
 | 
						|
            foreach (var cb in ComboBoxInputs)
 | 
						|
                cb.SelectedItem = null;
 | 
						|
            foreach (var cb in CheckBoxInputs)
 | 
						|
                cb.IsChecked = false;
 | 
						|
            foreach (var rb in RadioButtonInputs)
 | 
						|
                rb.IsChecked = false;
 | 
						|
            ValidateRequiredInputs();
 | 
						|
        }
 | 
						|
 | 
						|
        protected bool IsValid => Valid.All(kv => kv.Value);
 | 
						|
 | 
						|
        protected bool GetInputValid(Control input) {
 | 
						|
            return Valid[input];
 | 
						|
        }
 | 
						|
 | 
						|
        protected bool InputHasChanged(Control input) {
 | 
						|
            if (!OriginalValues.ContainsKey(input)) {
 | 
						|
                return false;
 | 
						|
            } else if (input is TextBox tb) {
 | 
						|
                return OriginalValues[tb]?.ToString() != tb.Text;
 | 
						|
            } else if (input is ComboBox sb) {
 | 
						|
                return OriginalValues[sb] != sb.SelectedItem;
 | 
						|
            } else if (input is CheckBox cb) {
 | 
						|
                return (OriginalValues[cb] != null) != (cb.IsChecked ?? false);
 | 
						|
            } else if (input is RadioButton rb) {
 | 
						|
                return (OriginalValues[rb] != null) != (rb.IsChecked ?? false);
 | 
						|
            } else {
 | 
						|
                return false;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        protected bool HasChanged =>
 | 
						|
            !IsValid ||
 | 
						|
            TextBoxInputs.Any(InputHasChanged) ||
 | 
						|
            ComboBoxInputs.Any(InputHasChanged) ||
 | 
						|
            CheckBoxInputs.Any(InputHasChanged) ||
 | 
						|
            RadioButtonInputs.Any(InputHasChanged);
 | 
						|
 | 
						|
        protected void UpdatePlz(TextBox plzInput, ComboBox ortInput) {
 | 
						|
            var plzInputValid = GetInputValid(plzInput);
 | 
						|
            var item = ortInput.SelectedItem;
 | 
						|
            var list = plzInputValid && plzInput.Text.Length == 4 ? Context.Postleitzahlen.Find(int.Parse(plzInput.Text))?.Orte.ToList() : null;
 | 
						|
            Utils.RenewItemsSource(ortInput, list, i => (i as AT_PlzDest)?.Id);
 | 
						|
            if (list != null && ortInput.SelectedItem == null && list.Count == 1)
 | 
						|
                ortInput.SelectedItem = list[0];
 | 
						|
            UpdateComboBox(ortInput);
 | 
						|
        }
 | 
						|
 | 
						|
        protected bool InputTextChanged(TextBox input, Func<TextBox, bool, ValidationResult> checker) {
 | 
						|
            return InputTextChanged(input, (tb, required, ctx) => checker(tb, required));
 | 
						|
        }
 | 
						|
 | 
						|
        protected bool InputTextChanged(TextBox input, Func<TextBox, bool, AppDbContext, ValidationResult> checker) {
 | 
						|
            return InputTextChanged(input, checker(input, SenderIsRequired(input), Context));
 | 
						|
        }
 | 
						|
 | 
						|
        protected bool InputTextChanged(TextBox input, ValidationResult res) {
 | 
						|
            ValidateInput(input, res.IsValid);
 | 
						|
            if (res.IsValid) {
 | 
						|
                if (InputHasChanged(input)) {
 | 
						|
                    Utils.SetInputChanged(input);
 | 
						|
                } else {
 | 
						|
                    Utils.ClearInputState(input);
 | 
						|
                }
 | 
						|
            } else {
 | 
						|
                Utils.SetInputInvalid(input);
 | 
						|
            }
 | 
						|
            UpdateButtons();
 | 
						|
            return res.IsValid;
 | 
						|
        }
 | 
						|
 | 
						|
        protected bool InputLostFocus(TextBox input, Func<TextBox, bool, ValidationResult> checker, string? msg = null) {
 | 
						|
            return InputLostFocus(input, (tb, requiered, ctx) => checker(tb, requiered), msg);
 | 
						|
        }
 | 
						|
 | 
						|
        protected bool InputLostFocus(TextBox input, Func<TextBox, bool, AppDbContext, ValidationResult> checker, string? msg = null) {
 | 
						|
            return InputLostFocus(input, checker(input, SenderIsRequired(input), Context), msg);
 | 
						|
        }
 | 
						|
 | 
						|
        protected bool InputLostFocus(TextBox input, ValidationResult res, string? msg = null) {
 | 
						|
            if (!res.IsValid && !IsClosing)
 | 
						|
                System.Windows.MessageBox.Show(res.ErrorContent.ToString(), msg ?? res.ErrorContent.ToString(), MessageBoxButton.OK, MessageBoxImage.Warning);
 | 
						|
            return res.IsValid;
 | 
						|
        }
 | 
						|
 | 
						|
        protected void CheckBox_Changed(object sender, RoutedEventArgs evt) {
 | 
						|
            var input = (CheckBox)sender;
 | 
						|
            if (SenderIsRequired(input) && input.IsChecked != true) {
 | 
						|
                Utils.SetInputInvalid(input);
 | 
						|
            } else if (InputHasChanged(input)) {
 | 
						|
                Utils.SetInputChanged(input);
 | 
						|
            } else {
 | 
						|
                Utils.ClearInputState(input);
 | 
						|
            }
 | 
						|
            UpdateButtons();
 | 
						|
        }
 | 
						|
 | 
						|
        protected void RadioButton_Changed(object sender, RoutedEventArgs evt) {
 | 
						|
            var input = (RadioButton)sender;
 | 
						|
            if (SenderIsRequired(input) && input.IsChecked != true) {
 | 
						|
                Utils.SetInputInvalid(input);
 | 
						|
            } else if (InputHasChanged(input)) {
 | 
						|
                Utils.SetInputChanged(input);
 | 
						|
            } else {
 | 
						|
                Utils.ClearInputState(input);
 | 
						|
            }
 | 
						|
            UpdateButtons();
 | 
						|
        }
 | 
						|
 | 
						|
        protected void TextBox_TextChanged(object sender, RoutedEventArgs evt) {
 | 
						|
            var input = (TextBox)sender;
 | 
						|
            if (SenderIsRequired(input) && input.Text.Length == 0) {
 | 
						|
                ValidateInput(input, false);
 | 
						|
                Utils.SetInputInvalid(input);
 | 
						|
            } else {
 | 
						|
                ValidateInput(input, true);
 | 
						|
                if (InputHasChanged(input)) {
 | 
						|
                    Utils.SetInputChanged(input);
 | 
						|
                } else {
 | 
						|
                    Utils.ClearInputState(input);
 | 
						|
                }
 | 
						|
            }
 | 
						|
            UpdateButtons();
 | 
						|
        }
 | 
						|
 | 
						|
        private void UpdateComboBox(Control input) {
 | 
						|
            bool valid = false;
 | 
						|
            if (input is ComboBox cb) {
 | 
						|
                valid = cb.ItemsSource == null || cb.SelectedItem != null || !RequiredInputs.Contains(input);
 | 
						|
            } else if (input is CheckComboBox ccb) {
 | 
						|
                valid = ccb.ItemsSource == null || ccb.SelectedItem != null || !RequiredInputs.Contains(input);
 | 
						|
            }
 | 
						|
            if (valid) {
 | 
						|
                ValidateInput(input, true);
 | 
						|
                if (InputHasChanged(input)) {
 | 
						|
                    Utils.SetInputChanged(input);
 | 
						|
                } else {
 | 
						|
                    Utils.ClearInputState(input);
 | 
						|
                }
 | 
						|
            } else {
 | 
						|
                ValidateInput(input, false);
 | 
						|
                Utils.SetInputInvalid(input);
 | 
						|
            }
 | 
						|
            UpdateButtons();
 | 
						|
        }
 | 
						|
 | 
						|
        protected void ComboBox_SelectionChanged(object sender, RoutedEventArgs evt) {
 | 
						|
            UpdateComboBox((Control)sender);
 | 
						|
        }
 | 
						|
 | 
						|
        protected void IntegerInput_TextChanged(object sender, RoutedEventArgs evt) {
 | 
						|
            InputTextChanged((TextBox)sender, Validator.CheckInteger);
 | 
						|
        }
 | 
						|
 | 
						|
        protected void PartialDateInput_TextChanged(object sender, RoutedEventArgs evt) {
 | 
						|
            InputTextChanged((TextBox)sender, Validator.CheckPartialDate);
 | 
						|
        }
 | 
						|
 | 
						|
        protected void PartialDateInput_LostFocus(object sender, RoutedEventArgs evt) {
 | 
						|
            InputLostFocus((TextBox)sender, Validator.CheckPartialDate);
 | 
						|
        }
 | 
						|
 | 
						|
        protected void DateInput_TextChanged(object sender, RoutedEventArgs evt) {
 | 
						|
            InputTextChanged((TextBox)sender, Validator.CheckDate);
 | 
						|
        }
 | 
						|
 | 
						|
        protected void DateInput_LostFocus(object sender, RoutedEventArgs evt) {
 | 
						|
            InputLostFocus((TextBox)sender, Validator.CheckDate);
 | 
						|
        }
 | 
						|
 | 
						|
        protected void PlzInput_TextChanged(object sender, RoutedEventArgs evt) {
 | 
						|
            var plz = (TextBox)sender;
 | 
						|
            InputTextChanged(plz, Validator.CheckPlz);
 | 
						|
            UpdatePlz(plz, GetPlzOrtInput(plz));
 | 
						|
        }
 | 
						|
 | 
						|
        protected void PlzInput_LostFocus(object sender, RoutedEventArgs evt) {
 | 
						|
            var plz = (TextBox)sender;
 | 
						|
            InputLostFocus(plz, Validator.CheckPlz);
 | 
						|
            UpdatePlz(plz, GetPlzOrtInput(plz));
 | 
						|
        }
 | 
						|
 | 
						|
        protected void EmailInput_TextChanged(object sender, RoutedEventArgs evt) {
 | 
						|
            InputTextChanged((TextBox)sender, Validator.CheckEmailAddress);
 | 
						|
        }
 | 
						|
 | 
						|
        protected void EmailInput_LostFocus(object sender, RoutedEventArgs evt) {
 | 
						|
            InputLostFocus((TextBox)sender, Validator.CheckEmailAddress);
 | 
						|
        }
 | 
						|
 | 
						|
        protected void PhoneNrInput_TextChanged(object sender, RoutedEventArgs evt) {
 | 
						|
            InputTextChanged((TextBox)sender, Validator.CheckPhoneNumber);
 | 
						|
        }
 | 
						|
 | 
						|
        protected void PhoneNrInput_LostFocus(object sender, RoutedEventArgs evt) {
 | 
						|
            InputLostFocus((TextBox)sender, Validator.CheckPhoneNumber);
 | 
						|
        }
 | 
						|
 | 
						|
        protected void IbanInput_TextChanged(object sender, RoutedEventArgs evt) {
 | 
						|
            InputTextChanged((TextBox)sender, Validator.CheckIban);
 | 
						|
        }
 | 
						|
 | 
						|
        protected void IbanInput_LostFocus(object sender, RoutedEventArgs evt) {
 | 
						|
            InputLostFocus((TextBox)sender, Validator.CheckIban);
 | 
						|
        }
 | 
						|
 | 
						|
        protected void BicInput_TextChanged(object sender, RoutedEventArgs evt) {
 | 
						|
            InputTextChanged((TextBox)sender, Validator.CheckBic);
 | 
						|
        }
 | 
						|
 | 
						|
        protected void BicInput_LostFocus(object sender, RoutedEventArgs evt) {
 | 
						|
            InputLostFocus((TextBox)sender, Validator.CheckBic);
 | 
						|
        }
 | 
						|
 | 
						|
        protected void UstIdInput_TextChanged(object sender, RoutedEventArgs evt) {
 | 
						|
            InputTextChanged((TextBox)sender, Validator.CheckUstId);
 | 
						|
        }
 | 
						|
 | 
						|
        protected void UstIdInput_LostFocus(object sender, RoutedEventArgs evt) {
 | 
						|
            InputLostFocus((TextBox)sender, Validator.CheckUstId);
 | 
						|
        }
 | 
						|
 | 
						|
        protected void LfbisNrInput_TextChanged(object sender, RoutedEventArgs evt) {
 | 
						|
            InputTextChanged((TextBox)sender, Validator.CheckLfbisNr);
 | 
						|
        }
 | 
						|
 | 
						|
        protected void LfbisNrInput_LostFocus(object sender, RoutedEventArgs evt) {
 | 
						|
            InputLostFocus((TextBox)sender, Validator.CheckLfbisNr);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |