mirror of
https://github.com/ckaczor/FeedCenter.git
synced 2026-02-17 02:51:37 -05:00
Validation WIP
This commit is contained in:
@@ -1,9 +1,10 @@
|
|||||||
using Realms;
|
using System;
|
||||||
using System;
|
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Realms;
|
||||||
|
|
||||||
namespace FeedCenter
|
namespace FeedCenter
|
||||||
{
|
{
|
||||||
@@ -11,13 +12,21 @@ namespace FeedCenter
|
|||||||
{
|
{
|
||||||
public const string DefaultName = "< default >";
|
public const string DefaultName = "< default >";
|
||||||
|
|
||||||
private readonly Dictionary<string, List<string>> _errorsByPropertyName = new();
|
private readonly DataErrorDictionary _dataErrorDictionary;
|
||||||
|
|
||||||
|
public Category()
|
||||||
|
{
|
||||||
|
_dataErrorDictionary = new DataErrorDictionary();
|
||||||
|
_dataErrorDictionary.ErrorsChanged += DataErrorDictionaryErrorsChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Ignored]
|
||||||
|
public ICollection<Feed> Feeds { get; set; }
|
||||||
|
|
||||||
[PrimaryKey]
|
[PrimaryKey]
|
||||||
public Guid Id { get; set; } = Guid.NewGuid();
|
public Guid Id { get; set; } = Guid.NewGuid();
|
||||||
|
|
||||||
[MapTo("Name")]
|
public bool IsDefault { get; internal set; }
|
||||||
private string RawName { get; set; } = string.Empty;
|
|
||||||
|
|
||||||
public string Name
|
public string Name
|
||||||
{
|
{
|
||||||
@@ -31,60 +40,37 @@ namespace FeedCenter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Ignored]
|
[MapTo("Name")]
|
||||||
public ICollection<Feed> Feeds { get; set; }
|
private string RawName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[UsedImplicitly]
|
||||||
|
public int SortKey => IsDefault ? 0 : 1;
|
||||||
|
|
||||||
|
public bool HasErrors => _dataErrorDictionary.Any();
|
||||||
|
|
||||||
|
public IEnumerable GetErrors(string propertyName)
|
||||||
|
{
|
||||||
|
return _dataErrorDictionary.GetErrors(propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
|
||||||
|
|
||||||
|
private void DataErrorDictionaryErrorsChanged(object sender, DataErrorsChangedEventArgs e)
|
||||||
|
{
|
||||||
|
ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(e.PropertyName));
|
||||||
|
}
|
||||||
|
|
||||||
public static Category CreateDefault()
|
public static Category CreateDefault()
|
||||||
{
|
{
|
||||||
return new Category { Name = DefaultName, IsDefault = true };
|
return new Category { Name = DefaultName, IsDefault = true };
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsDefault { get; internal set; }
|
|
||||||
|
|
||||||
// ReSharper disable once UnusedMember.Global
|
|
||||||
public int SortKey => IsDefault ? 0 : 1;
|
|
||||||
|
|
||||||
public bool HasErrors => _errorsByPropertyName.Any();
|
|
||||||
|
|
||||||
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
|
|
||||||
|
|
||||||
public IEnumerable GetErrors(string propertyName)
|
|
||||||
{
|
|
||||||
return _errorsByPropertyName.TryGetValue(propertyName, out var value) ? value : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnErrorsChanged(string propertyName)
|
|
||||||
{
|
|
||||||
ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ValidateName()
|
private void ValidateName()
|
||||||
{
|
{
|
||||||
ClearErrors(nameof(Name));
|
_dataErrorDictionary.ClearErrors(nameof(Name));
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(Name))
|
if (string.IsNullOrWhiteSpace(Name))
|
||||||
AddError(nameof(Name), "Name cannot be empty");
|
_dataErrorDictionary.AddError(nameof(Name), "Name cannot be empty");
|
||||||
}
|
|
||||||
|
|
||||||
private void AddError(string propertyName, string error)
|
|
||||||
{
|
|
||||||
if (!_errorsByPropertyName.ContainsKey(propertyName))
|
|
||||||
_errorsByPropertyName[propertyName] = new List<string>();
|
|
||||||
|
|
||||||
if (_errorsByPropertyName[propertyName].Contains(error))
|
|
||||||
return;
|
|
||||||
|
|
||||||
_errorsByPropertyName[propertyName].Add(error);
|
|
||||||
OnErrorsChanged(propertyName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ClearErrors(string propertyName)
|
|
||||||
{
|
|
||||||
if (!_errorsByPropertyName.ContainsKey(propertyName))
|
|
||||||
return;
|
|
||||||
|
|
||||||
_errorsByPropertyName.Remove(propertyName);
|
|
||||||
OnErrorsChanged(propertyName);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
43
Application/Feeds/DataErrorDictionary.cs
Normal file
43
Application/Feeds/DataErrorDictionary.cs
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
|
||||||
|
namespace FeedCenter
|
||||||
|
{
|
||||||
|
internal class DataErrorDictionary : Dictionary<string, List<string>>
|
||||||
|
{
|
||||||
|
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
|
||||||
|
|
||||||
|
private void OnErrorsChanged(string propertyName)
|
||||||
|
{
|
||||||
|
ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable GetErrors(string propertyName)
|
||||||
|
{
|
||||||
|
return TryGetValue(propertyName, out var value) ? value : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddError(string propertyName, string error)
|
||||||
|
{
|
||||||
|
if (!ContainsKey(propertyName))
|
||||||
|
this[propertyName] = new List<string>();
|
||||||
|
|
||||||
|
if (this[propertyName].Contains(error))
|
||||||
|
return;
|
||||||
|
|
||||||
|
this[propertyName].Add(error);
|
||||||
|
OnErrorsChanged(propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearErrors(string propertyName)
|
||||||
|
{
|
||||||
|
if (!ContainsKey(propertyName))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Remove(propertyName);
|
||||||
|
OnErrorsChanged(propertyName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,15 @@
|
|||||||
using System;
|
using ChrisKaczor.ApplicationUpdate;
|
||||||
|
using FeedCenter.Data;
|
||||||
|
using FeedCenter.FeedParsers;
|
||||||
|
using FeedCenter.Properties;
|
||||||
|
using FeedCenter.Xml;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Realms;
|
||||||
|
using Serilog;
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -9,14 +19,6 @@ using System.Net.Http.Headers;
|
|||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using ChrisKaczor.ApplicationUpdate;
|
|
||||||
using FeedCenter.Data;
|
|
||||||
using FeedCenter.FeedParsers;
|
|
||||||
using FeedCenter.Properties;
|
|
||||||
using FeedCenter.Xml;
|
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Realms;
|
|
||||||
using Serilog;
|
|
||||||
|
|
||||||
namespace FeedCenter
|
namespace FeedCenter
|
||||||
{
|
{
|
||||||
@@ -55,9 +57,18 @@ namespace FeedCenter
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public partial class Feed : RealmObject
|
public partial class Feed : RealmObject, INotifyDataErrorInfo
|
||||||
{
|
{
|
||||||
private static HttpClient _httpClient;
|
private static HttpClient _httpClient;
|
||||||
|
|
||||||
|
private readonly DataErrorDictionary _dataErrorDictionary;
|
||||||
|
|
||||||
|
public Feed()
|
||||||
|
{
|
||||||
|
_dataErrorDictionary = new DataErrorDictionary();
|
||||||
|
_dataErrorDictionary.ErrorsChanged += DataErrorDictionaryErrorsChanged;
|
||||||
|
}
|
||||||
|
|
||||||
public bool Authenticate { get; set; }
|
public bool Authenticate { get; set; }
|
||||||
|
|
||||||
public Guid CategoryId { get; set; }
|
public Guid CategoryId { get; set; }
|
||||||
@@ -112,17 +123,68 @@ namespace FeedCenter
|
|||||||
|
|
||||||
private string MultipleOpenActionRaw { get; set; }
|
private string MultipleOpenActionRaw { get; set; }
|
||||||
|
|
||||||
public string Name { get; set; }
|
public string Name
|
||||||
|
{
|
||||||
|
get => RawName;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
RawName = value;
|
||||||
|
|
||||||
|
ValidateString(nameof(Name), RawName);
|
||||||
|
RaisePropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
public string Source { get; set; }
|
|
||||||
|
[MapTo("Name")]
|
||||||
|
private string RawName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[MapTo("Source")]
|
||||||
|
private string RawSource { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string Source
|
||||||
|
{
|
||||||
|
get => RawSource;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
RawSource = value;
|
||||||
|
|
||||||
|
ValidateString(nameof(Source), RawSource);
|
||||||
|
RaisePropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
public string Username { get; set; }
|
public string Username { get; set; }
|
||||||
|
|
||||||
|
public bool HasErrors => _dataErrorDictionary.Any();
|
||||||
|
|
||||||
|
public IEnumerable GetErrors(string propertyName)
|
||||||
|
{
|
||||||
|
return _dataErrorDictionary.GetErrors(propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
|
||||||
|
|
||||||
public static Feed Create()
|
public static Feed Create()
|
||||||
{
|
{
|
||||||
return new Feed { Id = Guid.NewGuid(), CategoryId = Database.Entities.DefaultCategory.Id };
|
return new Feed { Id = Guid.NewGuid(), CategoryId = Database.Entities.DefaultCategory.Id };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DataErrorDictionaryErrorsChanged(object sender, DataErrorsChangedEventArgs e)
|
||||||
|
{
|
||||||
|
ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(e.PropertyName));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ValidateString(string propertyName, string value)
|
||||||
|
{
|
||||||
|
_dataErrorDictionary.ClearErrors(propertyName);
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(value))
|
||||||
|
_dataErrorDictionary.AddError(propertyName, $"{propertyName} cannot be empty");
|
||||||
|
}
|
||||||
|
|
||||||
#region Reading
|
#region Reading
|
||||||
|
|
||||||
public FeedReadResult Read(bool forceRead = false)
|
public FeedReadResult Read(bool forceRead = false)
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
Target="{Binding ElementName=NameTextBox}" />
|
Target="{Binding ElementName=NameTextBox}" />
|
||||||
<TextBox Name="NameTextBox"
|
<TextBox Name="NameTextBox"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged, ValidatesOnExceptions=True}">
|
Text="{Binding Path=Name, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}">
|
||||||
</TextBox>
|
</TextBox>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel
|
<StackPanel
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using ChrisKaczor.Wpf.Validation;
|
using System.Windows;
|
||||||
using System.Windows;
|
using ChrisKaczor.Wpf.Validation;
|
||||||
using FeedCenter.Data;
|
using FeedCenter.Data;
|
||||||
|
|
||||||
namespace FeedCenter.Options
|
namespace FeedCenter.Options
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
using ChrisKaczor.Wpf.Validation;
|
using System.Linq;
|
||||||
using FeedCenter.Data;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Data;
|
using System.Windows.Data;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
using ChrisKaczor.Wpf.Validation;
|
||||||
|
using FeedCenter.Data;
|
||||||
|
|
||||||
namespace FeedCenter.Options
|
namespace FeedCenter.Options
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user