Guest User

Untitled

a guest
Dec 11th, 2018
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.28 KB | None | 0 0
  1. if (bindingGroup.CommitEdit())
  2. SaveEverything();
  3.  
  4. object OnUpdateSourceExceptionFilter(object bindExpression, Exception exception)
  5. {
  6. BindingExpression expr = (bindExpression as BindingExpression);
  7. if (expr.DataItem is IReceivesBindingErrorInformation)
  8. {
  9. ((IReceivesBindingErrorInformation)expr.DataItem).ReceiveBindingErrorInformation(expr.ParentBinding.Path.Path, exception);
  10. }
  11.  
  12. // check for FormatException and produce a nicer error
  13. // ...
  14. }
  15.  
  16. HashSet<string> bindingErrors = new HashSet<string>();
  17. void IReceivesBindingErrorInformation.ReceiveBindingErrorInformation(string path, Exception exception)
  18. {
  19. bindingErrors.Add(path);
  20. }
  21.  
  22. protected ObservableCollection<string> errors = new ObservableCollection<string>();
  23.  
  24. public virtual ObservableCollection<string> Errors
  25. {
  26. get { return errors; }
  27. }
  28.  
  29. protected ObservableCollection<string> externalErrors = new ObservableCollection<string>();
  30.  
  31. public ObservableCollection<string> ExternalErrors
  32. {
  33. get { return externalErrors; }
  34. }
  35.  
  36. public virtual bool HasError
  37. {
  38. get { return Errors != null && Errors.Count > 0; }
  39. }
  40.  
  41. public override ObservableCollection<string> Errors
  42. {
  43. get
  44. {
  45. errors = new ObservableCollection<string>();
  46. errors.AddUniqueIfNotEmpty(this["Name"]);
  47. errors.AddUniqueIfNotEmpty(this["EmailAddresses"]);
  48. errors.AddUniqueIfNotEmpty(this["SomeOtherProperty"]);
  49. errors.AddRange(ExternalErrors);
  50. return errors;
  51. }
  52. }
  53.  
  54. public override string this[string propertyName]
  55. {
  56. get
  57. {
  58. string error = string.Empty;
  59. if (propertyName == "Name" && Name.IsNullOrEmpty()) error = "You must enter the Name field.";
  60. else if (propertyName == "EmailAddresses" && EmailAddresses.Count == 0) error = "You must enter at least one e-mail address into the Email address(es) field.";
  61. else if (propertyName == "SomeOtherProperty" && SomeOtherProperty.IsNullOrEmpty()) error = "You must enter the SomeOtherProperty field.";
  62. return error;
  63. }
  64. }
  65.  
  66. private void ValidateUniqueName(Genre genre)
  67. {
  68. string errorMessage = "The genre name must be unique";
  69. if (!IsGenreNameUnique(genre))
  70. {
  71. if (!genre.ExternalErrors.Contains(errorMessage)) genre.ExternalErrors.Add(errorMessage);
  72. }
  73. else genre.ExternalErrors.Remove(errorMessage);
  74. }
  75.  
  76. private bool IsGenreNameUnique(Genre genre)
  77. {
  78. return Genres.Where(d => d.Name != string.Empty && d.Name == genre.Name).Count() == 1;
  79. }
  80.  
  81. public object FooObject { get; set; } // Implement INotifyPropertyChanged
  82.  
  83. public int Foo
  84. {
  85. get { return FooObject.GetType() == typeof(int) ? int.Parse(FooObject) : -1; }
  86. }
  87.  
  88. public override string this[string propertyName]
  89. {
  90. get
  91. {
  92. string error = string.Empty;
  93. if (propertyName == "FooObject" && FooObject.GetType() != typeof(int))
  94. error = "Please enter a whole number for the Foo field.";
  95. ...
  96. return error;
  97. }
  98. }
  99.  
  100. container.AddHandler(Validation.ErrorEvent, Container_Error);
  101.  
  102. ...
  103.  
  104. void Container_Error(object sender, ValidationErrorEventArgs e) {
  105. ...
  106. }
  107.  
  108. public struct Failable<T>
  109. {
  110. public T Value { get; private set; }
  111. public string Text { get; private set; }
  112. public bool IsValid { get; private set; }
  113.  
  114. public Failable(T value)
  115. {
  116. Value = value;
  117.  
  118. try
  119. {
  120. var converter = TypeDescriptor.GetConverter(typeof(T));
  121. Text = converter.ConvertToString(value);
  122. IsValid = true;
  123. }
  124. catch
  125. {
  126. Text = String.Empty;
  127. IsValid = false;
  128. }
  129. }
  130.  
  131. public Failable(string text)
  132. {
  133. Text = text;
  134.  
  135. try
  136. {
  137. var converter = TypeDescriptor.GetConverter(typeof(T));
  138. Value = (T)converter.ConvertFromString(text);
  139. IsValid = true;
  140. }
  141. catch
  142. {
  143. Value = default(T);
  144. IsValid = false;
  145. }
  146. }
  147. }
  148.  
  149. public class StringToFailableConverter<T> : IValueConverter
  150. {
  151. public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  152. {
  153. if (value.GetType() != typeof(Failable<T>))
  154. throw new InvalidOperationException("Invalid value type.");
  155.  
  156. if (targetType != typeof(string))
  157. throw new InvalidOperationException("Invalid target type.");
  158.  
  159. var rawValue = (Failable<T>)value;
  160. return rawValue.Text;
  161. }
  162.  
  163. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  164. {
  165. if (value.GetType() != typeof(string))
  166. throw new InvalidOperationException("Invalid value type.");
  167.  
  168. if (targetType != typeof(Failable<T>))
  169. throw new InvalidOperationException("Invalid target type.");
  170.  
  171. return new Failable<T>(value as string);
  172. }
  173. }
  174.  
  175. public static class Failable
  176. {
  177. public static StringToFailableConverter<Int32> Int32Converter { get; private set; }
  178. public static StringToFailableConverter<double> DoubleConverter { get; private set; }
  179.  
  180. static Failable()
  181. {
  182. Int32Converter = new StringToFailableConverter<Int32>();
  183. DoubleConverter = new StringToFailableConverter<Double>();
  184. }
  185. }
  186.  
  187. public Failable<int> NumberValue
  188. {
  189. //Custom logic along with validation
  190. //using IsValid property
  191. }
  192.  
  193. <TextBox Text="{Binding NumberValue,Converter={x:Static local:Failable.Int32Converter}}"/>
  194.  
  195. public abstract class ViewModelBase : INotifyPropertyChanged
  196. {
  197. public event PropertyChangedEventHandler PropertyChanged;
  198.  
  199. public void RaisePropertyChanged([CallerMemberName] string propertyName = null)
  200. {
  201. if (PropertyChanged != null)
  202. PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
  203. }
  204. }
  205.  
  206. public class VmSomeEntity : ViewModelBase, INotifyDataErrorInfo
  207. {
  208. //This one is part of INotifyDataErrorInfo interface which I will not use,
  209. //perhaps in more complicated scenarios it could be used to let some other VM know validation changed.
  210. public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
  211.  
  212. //will hold the errors found in validation.
  213. public Dictionary<string, string> ValidationErrors = new Dictionary<string, string>();
  214.  
  215. //the actual value - notice it is 'int' and not 'string'..
  216. private int storageCapacityInBytes;
  217.  
  218. //this is just to keep things sane - otherwise the view will not be able to send whatever the user throw at it.
  219. //we want to consume what the user throw at us and validate it - right? :)
  220. private string storageCapacityInBytesWrapper;
  221.  
  222. //This is a property to be served by the View.. important to understand the tactic used inside!
  223. public string StorageCapacityInBytes
  224. {
  225. get { return storageCapacityInBytesWrapper ?? storageCapacityInBytes.ToString(); }
  226. set
  227. {
  228. int result;
  229. var isValid = int.TryParse(value, out result);
  230. if (isValid)
  231. {
  232. storageCapacityInBytes = result;
  233. storageCapacityInBytesWrapper = null;
  234. RaisePropertyChanged();
  235. }
  236. else
  237. storageCapacityInBytesWrapper = value;
  238.  
  239. HandleValidationError(isValid, "StorageCapacityInBytes", "Not a number.");
  240. }
  241. }
  242.  
  243. //Manager for the dictionary
  244. private void HandleValidationError(bool isValid, string propertyName, string validationErrorDescription)
  245. {
  246. if (!string.IsNullOrEmpty(propertyName))
  247. {
  248. if (isValid)
  249. {
  250. if (ValidationErrors.ContainsKey(propertyName))
  251. ValidationErrors.Remove(propertyName);
  252. }
  253. else
  254. {
  255. if (!ValidationErrors.ContainsKey(propertyName))
  256. ValidationErrors.Add(propertyName, validationErrorDescription);
  257. else
  258. ValidationErrors[propertyName] = validationErrorDescription;
  259. }
  260. }
  261. }
  262.  
  263. // this is another part of the interface - will be called automatically
  264. public IEnumerable GetErrors(string propertyName)
  265. {
  266. return ValidationErrors.ContainsKey(propertyName)
  267. ? ValidationErrors[propertyName]
  268. : null;
  269. }
  270.  
  271. // same here, another part of the interface - will be called automatically
  272. public bool HasErrors
  273. {
  274. get
  275. {
  276. return ValidationErrors.Count > 0;
  277. }
  278. }
  279. }
Add Comment
Please, Sign In to add comment