From 7274b9b6b2a21b98fa176bff45ce4b6c5b06cddb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Erbsh=C3=A4u=C3=9Fer?= Date: Wed, 10 Jun 2020 17:43:30 +0200 Subject: [PATCH] Modified error handling to support ModelProperties with multiple errors to implement nested properties. --- ucalc/BillingWindow.xaml | 3 +- ucalc/BillingWindow.xaml.cs | 6 + ucalc/Controls/ErrorIcon.xaml | 11 +- ucalc/Controls/ErrorIcon.xaml.cs | 44 ++++-- ucalc/Models/AddressModel.cs | 39 ++++++ ucalc/Models/BankAccountModel.cs | 34 +++++ ucalc/Models/BillingModel.cs | 5 +- ucalc/Models/FlatModel.cs | 40 ++++++ ucalc/Models/HouseModel.cs | 49 ++++++- ucalc/Models/LandlordModel.cs | 62 ++------ ucalc/Models/Model.cs | 234 +++++++++++++++++++++++-------- ucalc/Pages/HousePage.xaml | 156 ++++++++++++++++++++- ucalc/Pages/HousePage.xaml.cs | 24 +++- ucalc/Pages/LandlordPage.xaml | 45 +++--- ucalc/Pages/SideBar.xaml | 8 +- 15 files changed, 598 insertions(+), 162 deletions(-) create mode 100644 ucalc/Models/AddressModel.cs create mode 100644 ucalc/Models/BankAccountModel.cs create mode 100644 ucalc/Models/FlatModel.cs diff --git a/ucalc/BillingWindow.xaml b/ucalc/BillingWindow.xaml index a97e0ef..88188a6 100644 --- a/ucalc/BillingWindow.xaml +++ b/ucalc/BillingWindow.xaml @@ -26,7 +26,8 @@ LoadCompleted="OnLandlordFrameLoadCompleted"/> - + diff --git a/ucalc/BillingWindow.xaml.cs b/ucalc/BillingWindow.xaml.cs index bbe6833..f645e51 100644 --- a/ucalc/BillingWindow.xaml.cs +++ b/ucalc/BillingWindow.xaml.cs @@ -43,5 +43,11 @@ namespace UCalc var page = (LandlordPage) ((Frame) sender).Content; page.Model = Model.LandlordModel; } + + private void OnHouseFrameLoadCompleted(object sender, NavigationEventArgs e) + { + var page = (HousePage) ((Frame) sender).Content; + page.Model = Model.HouseModel; + } } } \ No newline at end of file diff --git a/ucalc/Controls/ErrorIcon.xaml b/ucalc/Controls/ErrorIcon.xaml index 96a55f9..67af572 100644 --- a/ucalc/Controls/ErrorIcon.xaml +++ b/ucalc/Controls/ErrorIcon.xaml @@ -9,12 +9,13 @@ Height="16"> - - + + - + + @@ -31,7 +32,7 @@ diff --git a/ucalc/Controls/ErrorIcon.xaml.cs b/ucalc/Controls/ErrorIcon.xaml.cs index c307840..31bc7b5 100644 --- a/ucalc/Controls/ErrorIcon.xaml.cs +++ b/ucalc/Controls/ErrorIcon.xaml.cs @@ -1,19 +1,18 @@ using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Runtime.CompilerServices; using System.Windows; using System.Windows.Data; +using ucalc.Annotations; namespace UCalc.Controls { - public class ErrorToVisibilityConverter : IValueConverter + public class ErrorsToVisibilityConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { - if (value == null || "".Equals(value)) - { - return Visibility.Collapsed; - } - - return Visibility.Visible; + return (((ICollection) value)?.Count ?? 0) == 0 ? Visibility.Collapsed : Visibility.Visible; } public object ConvertBack(object value, Type targetType, object parameter, @@ -23,9 +22,9 @@ namespace UCalc.Controls } } - public class ErrorToInVisibilityConverter : IValueConverter + public class ErrorsToInVisibilityConverter : IValueConverter { - private readonly ErrorToVisibilityConverter _converter = new ErrorToVisibilityConverter(); + private readonly ErrorsToVisibilityConverter _converter = new ErrorsToVisibilityConverter(); public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { @@ -40,16 +39,35 @@ namespace UCalc.Controls } } - public partial class ErrorIcon + public partial class ErrorIcon : INotifyPropertyChanged { - public string Error { get; set; } + public ICollection Errors { get; set; } - public static readonly DependencyProperty ErrorProperty = DependencyProperty.Register( - "Error", typeof(string), typeof(ErrorIcon), new PropertyMetadata((string) null)); + public string ErrorsToolTip { get; private set; } + + public static readonly DependencyProperty ErrorsProperty = DependencyProperty.Register( + "Errors", typeof(ICollection), typeof(ErrorIcon), + new PropertyMetadata(null, OnErrorsChanged)); public ErrorIcon() { InitializeComponent(); } + + private static void OnErrorsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var self = (ErrorIcon) d; + var newErrors = (ICollection) e.NewValue; + self.ErrorsToolTip = newErrors.Count > 0 ? string.Join("\n", newErrors) : null; + self.OnPropertyChanged("ErrorsToolTip"); + } + + public event PropertyChangedEventHandler PropertyChanged; + + [NotifyPropertyChangedInvocator] + private void OnPropertyChanged([CallerMemberName] string propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } } } \ No newline at end of file diff --git a/ucalc/Models/AddressModel.cs b/ucalc/Models/AddressModel.cs new file mode 100644 index 0000000..43d1bd7 --- /dev/null +++ b/ucalc/Models/AddressModel.cs @@ -0,0 +1,39 @@ +using UCalc.Data; + +namespace UCalc.Models +{ + public class AddressModel : Model + { + private readonly Address _data; + public ModelProperty Street { get; } + public ModelProperty HouseNumber { get; } + public ModelProperty City { get; } + public ModelProperty Postcode { get; } + + public AddressModel(Address data) + { + _data = data; + + Street = Add(new ModelProperty("Straße", _data.Street, ModelPropertyValidators.IsNotEmpty)); + HouseNumber = + Add(new ModelProperty("Hausnummer", _data.HouseNumber, ModelPropertyValidators.IsNotEmpty)); + City = Add(new ModelProperty("Stadt", _data.City, ModelPropertyValidators.IsNotEmpty)); + Postcode = Add(new ModelProperty("PLZ", _data.Postcode, ModelPropertyValidators.IsNotEmpty)); + } + + public override void Apply() + { + _data.Street = Street.Value; + Street.ResetModified(); + + _data.HouseNumber = HouseNumber.Value; + HouseNumber.ResetModified(); + + _data.City = City.Value; + City.ResetModified(); + + _data.Postcode = Postcode.Value; + Postcode.ResetModified(); + } + } +} \ No newline at end of file diff --git a/ucalc/Models/BankAccountModel.cs b/ucalc/Models/BankAccountModel.cs new file mode 100644 index 0000000..8160bc0 --- /dev/null +++ b/ucalc/Models/BankAccountModel.cs @@ -0,0 +1,34 @@ +using UCalc.Data; + +namespace UCalc.Models +{ + public class BankAccountModel : Model + { + private readonly BankAccount _data; + public ModelProperty Iban { get; } + public ModelProperty Bic { get; } + public ModelProperty BankName { get; } + + public BankAccountModel(BankAccount data) + { + _data = data; + + Iban = Add(new ModelProperty("IBAN", _data.Iban, ModelPropertyValidators.IsNotEmpty)); + Bic = Add(new ModelProperty("BIC", _data.Bic, ModelPropertyValidators.IsNotEmpty)); + BankName = Add(new ModelProperty("Name der Bank", _data.BankName, + ModelPropertyValidators.IsNotEmpty)); + } + + public override void Apply() + { + _data.Iban = Iban.Value; + Iban.ResetModified(); + + _data.Bic = Bic.Value; + Bic.ResetModified(); + + _data.BankName = BankName.Value; + BankName.ResetModified(); + } + } +} \ No newline at end of file diff --git a/ucalc/Models/BillingModel.cs b/ucalc/Models/BillingModel.cs index 58c6514..5d6bcc5 100644 --- a/ucalc/Models/BillingModel.cs +++ b/ucalc/Models/BillingModel.cs @@ -5,17 +5,18 @@ namespace UCalc.Models public class BillingModel : Model { public LandlordModel LandlordModel { get; } + public HouseModel HouseModel { get; } public BillingModel(Billing billing) { LandlordModel = new LandlordModel(billing.Landlord); - - Properties = LandlordModel.Properties; + HouseModel = new HouseModel(billing.House); } public override void Apply() { LandlordModel.Apply(); + HouseModel.Apply(); } } } \ No newline at end of file diff --git a/ucalc/Models/FlatModel.cs b/ucalc/Models/FlatModel.cs new file mode 100644 index 0000000..6cd98d1 --- /dev/null +++ b/ucalc/Models/FlatModel.cs @@ -0,0 +1,40 @@ +using System.Collections.Generic; +using System.Linq; +using UCalc.Data; + +namespace UCalc.Models +{ + public class FlatModel : Model + { + public Flat Data { get; } + public ModelProperty Name { get; } + public ModelProperty Size { get; } + + public FlatModel(Flat data, IReadOnlyList flats) + { + Data = data; + + Name = Add(new ModelProperty("Name", Data.Name, (name, value) => + { + var error = ModelPropertyValidators.IsNotEmpty(name, value); + + if (error == "" && flats.Any(flat => !ReferenceEquals(flat, Data) && flat.Name == value)) + { + error = $"{name}: Der Wert \"{value}\" ist nicht eindeutig."; + } + + return error; + })); + Size = Add(new ModelProperty("Größe", Data.Size.ToString(), ModelPropertyValidators.IsNaturalInt)); + } + + public override void Apply() + { + Data.Name = Name.Value; + Name.ResetModified(); + + Data.Size = int.TryParse(Size.Value, out var n) && n > 0 ? n : 0; + Size.ResetModified(); + } + } +} \ No newline at end of file diff --git a/ucalc/Models/HouseModel.cs b/ucalc/Models/HouseModel.cs index 3e1adac..9ad0cd0 100644 --- a/ucalc/Models/HouseModel.cs +++ b/ucalc/Models/HouseModel.cs @@ -5,16 +5,53 @@ namespace UCalc.Models public class HouseModel : Model { private readonly House _data; - public ModelProperty Street { get; } - public ModelProperty HouseNumber { get; } - public ModelProperty City { get; } - public ModelProperty Postcode { get; } - - // TODO: Flats? + public NestedModelProperty Address { get; } + public MultiModelProperty Flats { get; } public HouseModel(House data) { _data = data; + + Address = Add(new NestedModelProperty(new AddressModel(_data.Address))); + Flats = Add(new MultiModelProperty()); + + foreach (var flat in data.Flats) + { + Flats.Add(new FlatModel(flat, _data.Flats)); + } + } + + public override void Apply() + { + Address.Model.Apply(); + + foreach (var model in Flats.Models) + { + model.Apply(); + } + } + + public FlatModel AddFlat() + { + var flat = new Flat {Name = $"Wohnung {_data.Flats.Count + 1}"}; + _data.Flats.Add(flat); + + var model = new FlatModel(flat, _data.Flats); + Flats.Add(model); + + return model; + } + + public void RemoveFlat(FlatModel model) + { + _data.Flats.Remove(model.Data); + + Flats.Remove(model); + + if (model.Errors.Count > 0) + { + OnPropertyChanged("Errors"); + } } } } \ No newline at end of file diff --git a/ucalc/Models/LandlordModel.cs b/ucalc/Models/LandlordModel.cs index d76bb68..adf3658 100644 --- a/ucalc/Models/LandlordModel.cs +++ b/ucalc/Models/LandlordModel.cs @@ -9,71 +9,39 @@ namespace UCalc.Models public ModelProperty Name { get; } public ModelProperty MailAddress { get; } public ModelProperty Phone { get; } - public ModelProperty Street { get; } - public ModelProperty HouseNumber { get; } - public ModelProperty City { get; } - public ModelProperty Postcode { get; } - public ModelProperty Iban { get; } - public ModelProperty Bic { get; } - public ModelProperty BankName { get; } + public NestedModelProperty Address { get; } + public NestedModelProperty BankAccount { get; } public LandlordModel(Landlord data) { _data = data; - Salutation = new ModelProperty(this, (int) _data.Salutation, null); - Name = new ModelProperty(this, _data.Name, ModelPropertyValidators.IsNotEmpty); - MailAddress = new ModelProperty(this, _data.MailAddress, ModelPropertyValidators.IsNotEmpty); - Phone = new ModelProperty(this, _data.Phone, ModelPropertyValidators.IsNotEmpty); - Street = new ModelProperty(this, _data.Address.Street, ModelPropertyValidators.IsNotEmpty); - HouseNumber = - new ModelProperty(this, _data.Address.HouseNumber, ModelPropertyValidators.IsNotEmpty); - City = new ModelProperty(this, _data.Address.City, ModelPropertyValidators.IsNotEmpty); - Postcode = new ModelProperty(this, _data.Address.Postcode, ModelPropertyValidators.IsNotEmpty); - Iban = new ModelProperty(this, _data.BankAccount.Iban, ModelPropertyValidators.IsNotEmpty); - Bic = new ModelProperty(this, _data.BankAccount.Bic, ModelPropertyValidators.IsNotEmpty); - BankName = new ModelProperty(this, _data.BankAccount.BankName, ModelPropertyValidators.IsNotEmpty); - - Properties = new ModelProperty[] - {Salutation, Name, MailAddress, Phone, Street, HouseNumber, City, Postcode, Iban, Bic, BankName}; + Salutation = Add(new ModelProperty("Anrede", (int) _data.Salutation, null)); + Name = Add(new ModelProperty("Name", _data.Name, ModelPropertyValidators.IsNotEmpty)); + MailAddress = + Add(new ModelProperty("Email Adresse", _data.MailAddress, ModelPropertyValidators.IsNotEmpty)); + Phone = Add(new ModelProperty("Telefonnummer", _data.Phone, ModelPropertyValidators.IsNotEmpty)); + Address = Add(new NestedModelProperty(new AddressModel(_data.Address))); + BankAccount = Add(new NestedModelProperty(new BankAccountModel(_data.BankAccount))); } public override void Apply() { - base.Apply(); - _data.Salutation = (Salutation) Salutation.Value; - Salutation.Modified = false; + Salutation.ResetModified(); _data.Name = Name.Value; - Name.Modified = false; + Name.ResetModified(); _data.MailAddress = MailAddress.Value; - MailAddress.Modified = false; + MailAddress.ResetModified(); _data.Phone = Phone.Value; - Phone.Modified = false; + Phone.ResetModified(); - _data.Address.Street = Street.Value; - Street.Modified = false; + Address.Model.Apply(); - _data.Address.HouseNumber = HouseNumber.Value; - HouseNumber.Modified = false; - - _data.Address.City = City.Value; - City.Modified = false; - - _data.Address.Postcode = Postcode.Value; - Postcode.Modified = false; - - _data.BankAccount.Iban = Iban.Value; - Iban.Modified = false; - - _data.BankAccount.Bic = Bic.Value; - Bic.Modified = false; - - _data.BankAccount.BankName = BankName.Value; - BankName.Modified = false; + BankAccount.Model.Apply(); } } } \ No newline at end of file diff --git a/ucalc/Models/Model.cs b/ucalc/Models/Model.cs index 44e5e53..27dbc2a 100644 --- a/ucalc/Models/Model.cs +++ b/ucalc/Models/Model.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Runtime.CompilerServices; @@ -6,14 +8,107 @@ using ucalc.Annotations; namespace UCalc.Models { - public class ModelProperty : INotifyPropertyChanged + public abstract class ModelBaseProperty : INotifyPropertyChanged { - private readonly Model _model; - private object _value; - private string _error; - private readonly Func _validate; + protected static readonly List EmptyList = new List(); + public abstract IReadOnlyCollection Errors { get; } + public abstract bool Modified { get; } - public object Value + protected void OnChildPropertyChanged(object sender, PropertyChangedEventArgs args) + { + if (args.PropertyName == "Errors" || args.PropertyName == "Modified") + { + OnPropertyChanged(args.PropertyName); + } + } + + public event PropertyChangedEventHandler PropertyChanged; + + [NotifyPropertyChangedInvocator] + protected void OnPropertyChanged([CallerMemberName] string propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + } + + public class NestedModelProperty : ModelBaseProperty where T : Model + { + public T Model { get; } + + public NestedModelProperty(T model) + { + Model = model; + + Model.PropertyChanged += OnChildPropertyChanged; + } + + public override IReadOnlyCollection Errors => Model.Errors; + + public override bool Modified => Model.Modified; + } + + public class MultiModelProperty : ModelBaseProperty where T : Model + { + private readonly ObservableCollection _models; + + public MultiModelProperty() + { + _models = new ObservableCollection(); + } + + public void Add(T model) + { + _models.Add(model); + + model.PropertyChanged += OnChildPropertyChanged; + + if (model.Errors.Count > 0) + { + OnPropertyChanged("Errors"); + } + } + + public void Remove(T model) + { + model.PropertyChanged -= OnChildPropertyChanged; + + _models.Remove(model); + + if (model.Errors.Count > 0) + { + OnPropertyChanged("Errors"); + } + } + + public IReadOnlyList Models => _models; + + public override IReadOnlyCollection Errors + { + get + { + var errors = new List(); + + foreach (var model in _models) + { + errors.AddRange(model.Errors); + } + + return errors; + } + } + + public override bool Modified => _models.Select(model => model.Modified).Any(); + } + + public class ModelProperty : ModelBaseProperty + { + public string Name { get; } + private T _value; + private readonly List _errors; + private readonly Func _validate; + private bool _modified; + + public T Value { get => _value; set @@ -23,94 +118,115 @@ namespace UCalc.Models return; } - var oldError = Error; - Error = _validate?.Invoke(value); - if (oldError == null && Error != null || oldError != null && Error == null) + var oldError = _errors[0]; + _errors[0] = _validate?.Invoke(Name, value) ?? ""; + + if (oldError != _errors[0]) { - _model.OnPropertyChanged("ErrorCount"); + OnPropertyChanged("Errors"); } - Modified = true; + if (!_modified) + { + OnPropertyChanged("Modified"); + } + + _modified = true; _value = value; } } - public string Error + public ModelProperty(string name, T value, Func validate) { - get => _error; - private set - { - if (_error == value) - { - return; - } - - _error = value; - OnPropertyChanged(); - } - } - - public bool Modified { get; set; } - - public ModelProperty(Model model, object value, Func validate) - { - _model = model; + Name = name; _value = value; - _error = validate?.Invoke(value); + _errors = new List {validate?.Invoke(Name, _value) ?? ""}; _validate = validate; + _modified = false; } - public event PropertyChangedEventHandler PropertyChanged; + public override IReadOnlyCollection Errors => _errors[0] != "" ? _errors : EmptyList; - [NotifyPropertyChangedInvocator] - private void OnPropertyChanged([CallerMemberName] string propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - } + public override bool Modified => _modified; - public class ModelProperty : ModelProperty - { - public new T Value - { - get => (T) base.Value; - set => base.Value = value; - } - - public ModelProperty(Model model, T value, Func validate) : base(model, value, - validate == null ? (Func) null : o => validate((T) o)) + public void ResetModified() { + _modified = false; } } public static class ModelPropertyValidators { - public static string IsNotEmpty(string data) + public static string IsNotEmpty(string name, string data) { - return string.IsNullOrEmpty(data) ? "Geben Sie einen Wert ein" : null; + return string.IsNullOrEmpty(data) ? $"{name}: Geben Sie einen Wert ein." : ""; + } + + public static string IsNaturalInt(string name, string data) + { + return !int.TryParse(data, out var n) || n <= 0 + ? $"{name}: Der eingegebene Wert ist keine gültige positive Zahl > 0." + : ""; } } public abstract class Model : INotifyPropertyChanged { - public ModelProperty[] Properties { get; protected set; } + private readonly List _properties; - public bool Modified => Properties.Select(property => property.Modified).Any(); - - public int ErrorCount => Properties.Select(property => string.IsNullOrEmpty(property.Error) ? 0 : 1).Sum(); - - public virtual void Apply() + protected Model() { - if (ErrorCount > 0) + _properties = new List(); + + PropertyChanged += (sender, args) => { - throw new InvalidOperationException(); + if (args.PropertyName == "Errors") + { + OnPropertyChanged("ErrorCount"); + } + }; + } + + protected T Add(T property) where T : ModelBaseProperty + { + _properties.Add(property); + + property.PropertyChanged += (sender, args) => + { + if (args.PropertyName == "Errors" || args.PropertyName == "Modified") + { + OnPropertyChanged(args.PropertyName); + } + }; + + return property; + } + + public bool Modified => _properties.Select(property => property.Modified).Any(); + + public IReadOnlyCollection Errors + { + get + { + var errors = new List(); + + foreach (var property in _properties) + { + errors.AddRange(property.Errors); + } + + return errors; } } + public int ErrorCount => Errors.Count; + + public abstract void Apply(); + public event PropertyChangedEventHandler PropertyChanged; [NotifyPropertyChangedInvocator] - public void OnPropertyChanged([CallerMemberName] string propertyName = null) + protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } diff --git a/ucalc/Pages/HousePage.xaml b/ucalc/Pages/HousePage.xaml index 2737663..cd21e39 100644 --- a/ucalc/Pages/HousePage.xaml +++ b/ucalc/Pages/HousePage.xaml @@ -3,7 +3,157 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" - xmlns:local="clr-namespace:UCalc.Pages" + xmlns:local="clr-namespace:UCalc" + xmlns:pages="clr-namespace:UCalc.Pages" + xmlns:controls="clr-namespace:UCalc.Controls" mc:Ignorable="d"> - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ucalc/Pages/HousePage.xaml.cs b/ucalc/Pages/HousePage.xaml.cs index b2fba02..91ba23c 100644 --- a/ucalc/Pages/HousePage.xaml.cs +++ b/ucalc/Pages/HousePage.xaml.cs @@ -1,10 +1,32 @@ -namespace UCalc.Pages +using System.Windows; +using UCalc.Controls; +using UCalc.Models; + +namespace UCalc.Pages { public partial class HousePage { + public HouseModel Model { get; set; } + public HousePage() { InitializeComponent(); } + + private void OnAddFlatClick(object sender, RoutedEventArgs e) + { + Model.AddFlat(); + } + + private void OnFlatDeleteClick(object sender, RoutedEventArgs e) + { + var flatModel = (FlatModel) ((HighlightButton) sender).DataContext; + + if (MessageBox.Show($"Möchten Sie die Wohnung \"{flatModel.Data.Name}\" wirlick löschen?", "Löschen?", + MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes) + { + Model.RemoveFlat(flatModel); + } + } } } \ No newline at end of file diff --git a/ucalc/Pages/LandlordPage.xaml b/ucalc/Pages/LandlordPage.xaml index 6313a74..a6b06d2 100644 --- a/ucalc/Pages/LandlordPage.xaml +++ b/ucalc/Pages/LandlordPage.xaml @@ -6,7 +6,6 @@ xmlns:local="clr-namespace:UCalc" xmlns:pages="clr-namespace:UCalc.Pages" xmlns:controls="clr-namespace:UCalc.Controls" - xmlns:data="clr-namespace:UCalc.Data" mc:Ignorable="d"> - + @@ -32,7 +31,7 @@ + Errors="{Binding Path=Model.Name.Errors, RelativeSource={RelativeSource AncestorType=pages:LandlordPage}}" /> + Errors="{Binding Path=Model.Phone.Errors, RelativeSource={RelativeSource AncestorType=pages:LandlordPage}}" /> + Errors="{Binding Path=Model.MailAddress.Errors, RelativeSource={RelativeSource AncestorType=pages:LandlordPage}}" /> - + + Margin="0, 12, 0, 0" /> @@ -103,12 +102,12 @@ + Errors="{Binding Path=Model.Address.Model.HouseNumber.Errors, RelativeSource={RelativeSource AncestorType=pages:LandlordPage}}" /> + Text="{Binding Path=Model.Address.Model.HouseNumber.Value, RelativeSource={RelativeSource AncestorType=pages:LandlordPage}, UpdateSourceTrigger=PropertyChanged}" /> @@ -120,12 +119,12 @@ + Errors="{Binding Path=Model.Address.Model.City.Errors, RelativeSource={RelativeSource AncestorType=pages:LandlordPage}}" /> + Text="{Binding Path=Model.Address.Model.City.Value, RelativeSource={RelativeSource AncestorType=pages:LandlordPage}, UpdateSourceTrigger=PropertyChanged}" /> @@ -137,16 +136,16 @@ + Errors="{Binding Path=Model.Address.Model.Postcode.Errors, RelativeSource={RelativeSource AncestorType=pages:LandlordPage}}" /> + Text="{Binding Path=Model.Address.Model.Postcode.Value, RelativeSource={RelativeSource AncestorType=pages:LandlordPage}, UpdateSourceTrigger=PropertyChanged}" /> - + + Margin="0, 12, 0, 0" /> @@ -174,12 +173,12 @@ + Errors="{Binding Path=Model.BankAccount.Model.Bic.Errors, RelativeSource={RelativeSource AncestorType=pages:LandlordPage}}" /> + Text="{Binding Path=Model.BankAccount.Model.Bic.Value, RelativeSource={RelativeSource AncestorType=pages:LandlordPage}, UpdateSourceTrigger=PropertyChanged}" /> @@ -191,12 +190,12 @@ + Errors="{Binding Path=Model.BankAccount.Model.BankName.Errors, RelativeSource={RelativeSource AncestorType=pages:LandlordPage}}" /> + Text="{Binding Path=Model.BankAccount.Model.BankName.Value, RelativeSource={RelativeSource AncestorType=pages:LandlordPage}, UpdateSourceTrigger=PropertyChanged}" /> diff --git a/ucalc/Pages/SideBar.xaml b/ucalc/Pages/SideBar.xaml index 4431042..f78380e 100644 --- a/ucalc/Pages/SideBar.xaml +++ b/ucalc/Pages/SideBar.xaml @@ -116,8 +116,7 @@ - @@ -154,6 +153,11 @@ + +