public static void AddErrorMessage(this Page page, IDataErrorInfo obj, string validationGroup = null) { obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance) .Where(p => !String.IsNullOrWhiteSpace(obj[p.Name])) .Select(p => p.Name) .ToList() .ForEach(propertyName => AddErrorMessage(page, obj[propertyName], validationGroup)); }
static bool PropertyHasError(IDataErrorInfo owner, PropertyDescriptor property, int deep) { string simplePropertyError = owner[property.Name]; if(!string.IsNullOrEmpty(simplePropertyError)) return true; object propertyValue; if(!TryGetPropertyValue(owner, property.Name, out propertyValue)) return false; IDataErrorInfo nestedDataErrorInfo = propertyValue as IDataErrorInfo; return nestedDataErrorInfo != null && HasErrors(nestedDataErrorInfo, deep); }
/// <summary> /// Calls AddErrorMessage for all errormessages contained in an IDataErrorInfo-object /// </summary> /// <param name="obj">The object containing the error data.</param> /// <param name="validationGroup">The validationgroup to add the validators to.</param> public static void AddErrorMessage(this Page page, IDataErrorInfo obj, string validationGroup = null) { // Add all error-messages of the object to the validationsummary obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance) .Select(p => p.Name) .Where(n => !String.IsNullOrWhiteSpace(obj[n])) .ToList() .ForEach(n => AddErrorMessage(page, obj[n], validationGroup)); }
/// <summary> /// Checks the value core. /// </summary> /// <param name="validation">The validation.</param> /// <exception cref="ValidationException"></exception> protected static void CheckValueCore(IDataErrorInfo validation) { if (validation == null) throw new ArgumentNullException(nameof(validation), $"{nameof(validation)} is null."); var errors = validation.Error; if (string.IsNullOrEmpty(errors)) throw new ValidationException($"Validation errors: " + errors); }
public static bool HasErrors(IDataErrorInfo owner, bool ignoreOwnerError, int deep = 2) { if(owner == null) throw new ArgumentNullException("owner"); if(--deep < 0) return false; var properties = TypeDescriptor.GetProperties(owner).Cast<PropertyDescriptor>(); var errorProperty = properties.FirstOrDefault(p => p.Name == "Error"); bool hasImplicitImplementation = ExpressionHelper.PropertyHasImplicitImplementation(owner, o => o.Error, false); if(errorProperty != null && hasImplicitImplementation) { properties = properties.Except(new[] { errorProperty }); } bool propertiesHaveError = properties.Any(p => PropertyHasError(owner, p, deep)); return propertiesHaveError || (!ignoreOwnerError && !string.IsNullOrEmpty(owner.Error)); }
/// <summary> /// Validates object for all properties. /// </summary> /// <param name="model"></param> /// <returns></returns> public static string GetError(IDataErrorInfo model) { List<ValidationResult> results = new List<ValidationResult>(); ValidationContext context = new ValidationContext(model, null, null); if (!Validator.TryValidateObject(model, context, results)) { string v = string.Empty; results.ForEach((r) => v += r.ErrorMessage); return v; } return string.Empty; }
/// <summary> /// Validates object for the given property. /// </summary> /// <returns></returns> public static string GetError(IDataErrorInfo model, string columnName) { ValidationContext context = new ValidationContext(model, null, null) { MemberName = columnName }; object val = model.GetType().GetProperty(columnName).GetValue(model, null); List<ValidationResult> results = new List<ValidationResult>(); if (!Validator.TryValidateProperty(val, context, results)) { string v = string.Empty; results.ForEach((r) => v += r.ErrorMessage); return v; } return string.Empty; }
public LauncherViewModel(StrategyFinder finder, StrategyViewLauncher launcher, Settings settings) { if (finder == null) throw new ArgumentNullException("finder"); if (launcher == null) throw new ArgumentNullException("launcher"); if (settings == null) throw new ArgumentNullException("settings"); this.settings = settings; this.validations = new LauncherViewModelValidations(this); this.launcher = launcher; this.PriceTypes = new[] { new PriceType(StrategyLauncher.PriceType.Bid, "BID"), new PriceType(StrategyLauncher.PriceType.Ask, "ASK"), }; this.Periodicities = new[] { new Periodicity("S10", "10 Seconds"), new Periodicity("M1", "1 Minute"), new Periodicity("M5", "5 Minutes"), new Periodicity("M15", "15 Minutes"), new Periodicity("M30", "30 Minutes"), new Periodicity("H1", "1 Hour"), new Periodicity("H4", "1 Hours"), new Periodicity("W1", "1 Week"), new Periodicity("MN1", "1 Month"), }; this.Strategies = finder.Strategies; this.LaunchCommand = new ActionCommand(this.Launch, this.CanLaunch); }
/// <summary> /// Need to close current popup and open popup if current item has invalid property. /// </summary> /// <param name="sender">Ignored.</param> /// <param name="e">DataGridItemCancelEventArgs.</param> private void _CollectionViewSourceBeginningEdit(object sender, DataGridItemCancelEventArgs e) { // Do not show callout, when pointing on invalid cell. _StopTimer(); // If callout pointing at another item - close it. if (_InvalidItem != e.Item && _Callout.IsOpen) { _ClosePopup(true); _callout = new Callout(); } // Remember edited item and subscribe to it's property changed event. _InvalidItem = e.Item as IDataErrorInfo; (e.Item as INotifyPropertyChanged).PropertyChanged += new PropertyChangedEventHandler (_EditedItemPropertyChanged); // If current column have error. if (_dataGrid.CurrentColumn != null && !string.IsNullOrEmpty((e.Item as IDataErrorInfo)[_dataGrid.CurrentColumn.FieldName])) { // If callout is pointing at another column - close it. if (_column != _dataGrid.CurrentColumn) { _ClosePopup(true); _callout = new Callout(); } // If callout closed - open it and point at current cell. if (!_Callout.IsOpen) { // Detect column to show callout. var column = _dataGrid.CurrentColumn; if (Address.IsAddressPropertyName(column.FieldName)) column = _GetFirstAddressColumn(); _InitCallout(column); } } // If callout closed - seek for item's invalid properties. else if (!_Callout.IsOpen && !string.IsNullOrEmpty(_InvalidItem.Error)) _ShowCalloutOnInvalidItem(e.Item as IDataErrorInfo); // Subscribe to cell property changed events. Doing so we will know when user change active cell. DataRow row = _dataGrid.GetContainerFromItem(e.Item) as DataRow; // If grid view is table flow - even in editing state row can be null. if (row != null) foreach (var cell in row.Cells) cell.PropertyChanged += new PropertyChangedEventHandler(_CellPropertyChanged); }
public string GetValidationErrors() { IDataErrorInfo dataErrorInfo = (IDataErrorInfo)this; return(dataErrorInfo.Error); }
/// <summary> /// Går igenom samtliga publika egenskaper för obj och undersöker om felmeddelande finns som i så /// fall läggs till samlingen ValidatorCollection. /// </summary> /// <param name="obj">Referens till affärslogikobjekt.</param> private void AddErrorMessage(IDataErrorInfo obj) { // Hämtar och loopar igenom samtliga publika, icke statiska, egenskaper objektet har där det // finns det ett felmeddelande associerat med egenskapens namn. var propertyNames = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance) .Where(p => !String.IsNullOrWhiteSpace(obj[p.Name])) .Select(p => p.Name); foreach (var propertyName in propertyNames) { // Överför meddelandet till samlingen ValidatorCollection. AddErrorMessage(obj[propertyName]); } }
/// <summary> /// Updates the has errors property. /// </summary> /// <param name="dei">The instance.</param> public void UpdateHasErrors(IDataErrorInfo dei) { // validate all properties in this tab this.HasErrors = this.Groups.Any(g => g.Properties.Any(p => !string.IsNullOrEmpty(dei[p.PropertyName]))); }
public PersonTemplate() { validationTemplate = new ValidationTemplate(this); }
/// <summary> /// Return first visible column with error for this item. /// </summary> /// <param name="itemToCheck">Item, which property must be checked.</param> /// <returns>First visible column with error.</returns> private List<Column> _GetInvalidColumns(IDataErrorInfo itemToCheck) { List<Column> columns = new List<Column>(); // For each grid visible column. foreach (var column in _dataGrid.GetVisibleColumns()) { // Find error message for corresponding property. string error = itemToCheck[column.FieldName]; // If error message isn't empty. if (!string.IsNullOrEmpty(error)) columns.Add(column); } // If we come here - there is no invalid columns. return columns; }
/// <summary> /// When editing item property changed need to check its properties for errors. /// </summary> /// <param name="sender">IDataErrorInfo implementation.</param> /// <param name="e">Ignored.</param> private void _EditedItemPropertyChanged(object sender, PropertyChangedEventArgs e) { // Detect current column. var column = _dataGrid.CurrentColumn; // If grid view is table flow - current column can be null. if (column == null) return; // Edited property is address property - do not check anything. if (Address.IsAddressPropertyName(_dataGrid.CurrentColumn.FieldName)) return; // Set currently editing item as invalid item. _InvalidItem = sender as IDataErrorInfo; // If currently edited property is invalid - point callout at it. if (!string.IsNullOrEmpty(_InvalidItem[column.FieldName])) { // If current callout doesnt point at this cell - close callout // and open it on right place. if (_column != column) { _ClosePopup(true); _InitCallout(column); } // If callout closed - show it. else if (!_callout.IsOpen) _InitCallout(column); } // If currently edited property became valid or // if property on which callout is pointing became valid - // close callout and seek for another invalid property to point at. else if (_column == _dataGrid.CurrentColumn || (_column != null && string.IsNullOrEmpty(_InvalidItem[_column.FieldName]))) { _ClosePopup(true); _ShowCalloutOnInvalidItem(sender as IDataErrorInfo); } // If currently edited item has no errors - close popup. else if (string.IsNullOrEmpty((sender as IDataErrorInfo).Error)) _ClosePopup(true); }
// Helper class to provide a common set of tests for constructor-args based // multi-mocks testing. Exercises a mocked StringWriter (which should also be an IDataErrorInfo) // constructed with a mocked IFormatProvider. The test checks the semantics // of the mocked StringWriter to compare it with the expected semantics. private static void CommonConstructorArgsTest(StringBuilder stringBuilder, IFormatProvider formatProvider, StringWriter mockedWriter, MockType mockType) { string stringToWrite = "The original string"; string stringToWriteLine = "Extra bit"; IDataErrorInfo errorInfo = mockedWriter as IDataErrorInfo; Assert.NotNull(errorInfo); // Configure expectations for mocked writer mockedWriter.Stub(x => x.FormatProvider).Return(formatProvider).CallOriginalMethod(); mockedWriter.Expect(x => x.Write((string)null)).IgnoreArguments().CallOriginalMethod(); mockedWriter.Expect(x => x.Flush()).Repeat.Any().CallOriginalMethod(); mockedWriter.Expect(x => x.Close()); // Configure expectations for object through interface errorInfo.Expect(x => x.Error).Return(null); errorInfo.Expect(x => x.Error).Return("error!!!"); // Ensure that arguments arrived okay // Is the format provider correct Assert.Same(formatProvider, mockedWriter.FormatProvider); // Does writing to the writer forward to our stringbuilder from the constructor? mockedWriter.Write(stringToWrite); mockedWriter.Flush(); // Let's see what mode our mock is running in. // We have not configured WriteLine at all, so: // a) if we're running as a strict mock, it'll fail // b) if we're running as a dynamic mock, it'll no-op // c) if we're running as a partial mock, it'll work try { mockedWriter.WriteLine(stringToWriteLine); } catch (ExpectationViolationException) { // We're operating strictly. Assert.Equal(MockType.Strict, mockType); } string expectedStringBuilderContents = null; switch (mockType) { case MockType.Dynamic: case MockType.Strict: // The writeline won't have done anything expectedStringBuilderContents = stringToWrite; break; case MockType.Partial: // The writeline will have worked expectedStringBuilderContents = stringToWrite + stringToWriteLine + Environment.NewLine; break; } Assert.Equal(expectedStringBuilderContents, stringBuilder.ToString()); // Satisfy expectations. mockedWriter.Close(); Assert.Null(errorInfo.Error); Assert.Equal("error!!!", errorInfo.Error); if (MockType.Strict != mockType) { mockedWriter.VerifyAllExpectations(); } }
/// <summary> /// Determines all validation errors in this view model instance. /// </summary> /// <param name="maxCount">The maximum number of errors to return.</param> /// <returns>A dictionary that holds the error message for each property name.</returns> protected Dictionary <string, string> GetErrors(int maxCount = 5) { var dict = new Dictionary <string, string>(); int more = 0; string lastKey = null; string lastValue = null; List <object> objs = new List <object>(); objs.Add(this); AddErrorSubObjects(objs); foreach (object obj in objs) { IDataErrorInfo dei = obj as IDataErrorInfo; if (dei != null) { foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(obj)) { // Avoid recursion: These properties call the GetErrors method if (prop.Name == "Errors") { continue; } if (prop.Name == "HasErrors") { continue; } string msg = dei[prop.Name]; if (msg == null) { // Also try locally stored error messages msg = GetPropertyError(prop.Name); } if (msg != null) { if (dict.Count < maxCount) { dict[prop.Name] = msg; if (maxCount == 1) { return(dict); } } else { // Remember the last key and message in case it's the only one. // (We don't need to waste space with a "more" note when we can show // the actual single message instead.) lastKey = prop.Name; lastValue = msg; more++; } } } } } if (more == 1) { // There's only one more message, so show it dict[lastKey] = lastValue; } else if (more > 0) { // Add an item at the end, about how many more messages were not returned dict["zzz"] = string.Format(MoreErrorsMessage, more); } return(dict); }
public ValidableViewModelBase() { Validator = new ValidationHelper(); DataErrorInfoAdapter = new DataErrorInfoAdapter(Validator); OnCreated(); }
protected virtual bool HasValidationErrors() { IDataErrorInfo dataErrorInfo = Entity as IDataErrorInfo; return(dataErrorInfo != null && IDataErrorInfoHelper.HasErrors(dataErrorInfo)); }
/// <summary> /// Initializes a new instance of the <see cref="DataErrorInfoConverter" /> class. /// </summary> /// <param name="instance">The instance.</param> /// <param name="columnName">Name of the column.</param> public DataErrorInfoConverter(IDataErrorInfo instance, string columnName) { this.instance = instance; this.columnName = columnName; }
internal ValidationWrapper(ICEFInfraWrapper iw) { // If contained object implements IDataErrorInfo, support that "first" _source = iw.GetWrappedObject() as IDataErrorInfo; _iwsource = iw as IDataErrorInfo; }
/// <summary> /// Starting editing of new item. /// </summary> /// <param name="sender">Ignore.</param> /// <param name="e">DataGridItemEventArgs.</param> private void _CollectionViewSourceCreatingNewItem(object sender, DataGridItemEventArgs e) { // Stop timer and unsubscribe from mouse move events. _StopTimer(); // Turn off geocoding validation. if (e.Item is IGeocodable) (e.Item as IGeocodable).IsAddressValidationEnabled = false; // Close popup. _DeactivatePopup(true); // Remember edited item and subscribe to it's property changed event. _InvalidItem = e.Item as IDataErrorInfo; (e.Item as INotifyPropertyChanged).PropertyChanged += new PropertyChangedEventHandler (_EditedItemPropertyChanged); // If new item already has errors - show callout. _dataGrid.Dispatcher.BeginInvoke(new Action(delegate() { var column = _GetColumnWithError(_InvalidItem); if (column != null) _InitCallout(column); }), DispatcherPriority.ApplicationIdle); }
/// <summary> /// When mouse move in invalid cell - show corresponding popup. /// </summary> /// <param name="sender">Ignored.</param> /// <param name="e">Ignored.</param> private void _dataGridMouseMove(object sender, System.Windows.Input.MouseEventArgs e) { // Find cell on which mouse moved. Cell cell = XceedVisualTreeHelper.GetCellByEventArgs(e); // If cell has error, grid isnt in editing state and timer is running - show callout. if (cell != null && cell.HasValidationError && !_timer.IsEnabled && !_dataGrid.IsBeingEdited && !(_dataGrid.InsertionRow != null && _dataGrid.InsertionRow.IsBeingEdited)) { _showCallout = true; // Detect current column and item. Show callout. IDataErrorInfo currentItem = _dataGrid.GetItemFromContainer(cell) as IDataErrorInfo; var columns = _dataGrid.GetVisibleColumns(); _column = columns.FirstOrDefault(x => x.FieldName == cell.FieldName); _InvalidItem = currentItem; _SetPopupPosition(); _showCallout = false; // When mouse leave current cell - callout must be hided. cell.MouseLeave += new System.Windows.Input.MouseEventHandler(_MouseLeaveCellWithInvalidProperty); } }
private string GetDataErrorInfoMessage(string propertyName, IDataErrorInfo dataErrorInfo) { string item; try { item = dataErrorInfo[propertyName]; } catch (Exception e) { Debug.WriteLine(e.ToString()); if (e is OutOfMemoryException || e is StackOverflowException || e is AccessViolationException || e is ThreadAbortException) { throw; } return null; } return item; }
/// <summary> /// Return first visible column with error for this item. /// </summary> /// <param name="itemToCheck">Item, which property must be checked.</param> /// <returns>First visible column with error.</returns> private Column _GetColumnWithError(IDataErrorInfo itemToCheck) { // For each grid visible column. foreach (var column in _dataGrid.GetVisibleColumns()) { // Find error message for corresponding property. string error = itemToCheck[column.FieldName]; // If error message isn't empty. if (!string.IsNullOrEmpty(error)) return column; } // If we come here - there is no invalid columns. return null; }
/// <summary> /// If item has error in visible properies - show first of them. /// </summary> /// <param name="objectToValidate">IDataErrorInfo implementation.</param> private void _ShowCalloutOnInvalidItem(IDataErrorInfo objectToValidate) { // If there is nothing to validate - do nothing. if (objectToValidate == null) return; // Find column, corresponding to invalid property. Column column = _GetColumnWithError(objectToValidate); if (column != null) { _InvalidItem = objectToValidate; _InitCallout(column); } }
/// <summary> /// Check that row is shown in current grid layout. /// </summary> /// <param name="dataObject">Data object, which row must be checked.</param> /// <returns>'True' if row is shown, 'false' otherwise.</returns> private bool _IsItemVisible(IDataErrorInfo dataObject) { // Get row for this item. var row = _dataGrid.GetContainerFromItem(dataObject) as Row; if (row != null) { // Check that row is shown. var point = row.PointToScreen(new System.Windows.Point(0, row.Height)); return _IsPointInsideGrid(row, point); } return false; }
public static bool HasErrors(IDataErrorInfo owner, int deep = 2) { return(HasErrors(owner, false, deep)); }
/// <summary> /// Checks an IDEI data object for errors for the specified property. New errors are added to the /// list of validation results. /// </summary> /// <param name="idei">IDEI object to validate.</param> /// <param name="bindingProperty">Name of the property to validate.</param> /// <param name="bindingPath">Path of the binding.</param> /// <param name="validationResults">List of results to add to.</param> private void ValidateIdei(IDataErrorInfo idei, string bindingProperty, string bindingPath, List<ValidationResult> validationResults) { if (idei != null) { string errorString = null; if (string.IsNullOrEmpty(bindingProperty)) { Debug.Assert(string.IsNullOrEmpty(bindingPath)); ValidationUtil.CatchNonCriticalExceptions(() => { errorString = idei.Error; }); if (!string.IsNullOrEmpty(errorString)) { validationResults.AddIfNew(new ValidationResult(errorString)); } } else { ValidationUtil.CatchNonCriticalExceptions(() => { errorString = idei[bindingProperty]; }); if (!string.IsNullOrEmpty(errorString)) { ValidationResult validationResult = new ValidationResult(errorString, new List<string>() { bindingPath }); validationResults.AddIfNew(validationResult); this._propertyValidationResults.Add(validationResult); } } } }
public static bool HasErrors(IDataErrorInfo owner, int deep = 2) { return HasErrors(owner, false, deep); }
/// <summary> /// Initializes a new instance of the <see cref="DataErrorInfoConverter" /> class. /// </summary> /// <param name="instance">The instance.</param> /// <param name="columnName">Name of the column.</param> public DataErrorInfoConverter(IDataErrorInfo instance, string columnName) { this.instance = instance; this.columnName = columnName; }
/// <summary> /// Check that all items in collection are valid. /// </summary> private void _Validate() { if (App.Current.UIManager.IsLocked || !_dataGrid.IsVisible) { return; } // Need to stop timer. _StopTimer(); // Enable showing callout. _showCallout = true; // For all items in data grid source collection. foreach (var item in _collection) { // If item isn't valid. if ((item is IDataErrorInfo) && !(string.IsNullOrEmpty((item as IDataErrorInfo).Error))) { // Cast item to IDataErrorInfo. var dataObject = item as IDataErrorInfo; // Find first visible column with error. Column column = _GetColumnWithError(dataObject); if (column != null) { // Remeber data object as invalid item. _InvalidItem = dataObject; // If row with this item isn't shown in grid - show it. if (_IsItemVisible(dataObject)) { _dataGrid.BringItemIntoView(dataObject); } // Set grid's current item on invalid item. // There must be so much invoking, because grid is working async. _dataGrid.Dispatcher.BeginInvoke(new Action(delegate() { _dataGrid.CurrentItem = dataObject; // Show column with wrong property. _dataGrid.Dispatcher.BeginInvoke(new Action(delegate() { _dataGrid.CurrentColumn = column; // Show callout. _dataGrid.Dispatcher.BeginInvoke(new Action(delegate() { _InitCallout(column); _StartTimerSubscribeToEvent(); } ), DispatcherPriority.ContextIdle); }), DispatcherPriority.ContextIdle); }), DispatcherPriority.ContextIdle); // If we found invalid item - stop searching. return; } } } }
public void RegisterError(IDataErrorInfo vmdl) { _errorViewModels.Add(vmdl); }
/// <summary> /// Updates the has errors property. /// </summary> /// <param name="dei">The instance.</param> public void UpdateHasErrors(IDataErrorInfo dei) { // validate all properties in this tab this.HasErrors = this.Groups.Any(g => g.Properties.Any(p => !string.IsNullOrEmpty(dei[p.PropertyName]))); }
public static bool HasErrors(IDataErrorInfo owner, int deep = 2) { if(owner == null) throw new ArgumentNullException("owner"); if(--deep < 0) return false; return TypeDescriptor.GetProperties(owner).Cast<PropertyDescriptor>().Select(p => PropertyHasError(owner, p, deep)).Concat(new bool[] { !string.IsNullOrEmpty(owner.Error) }).Any(e => e); }
public static bool IsDataValid(this IDataErrorInfo target) { return(target.GetType() .GetProperties(BindingFlags.Public | BindingFlags.Instance) .All(p => String.IsNullOrWhiteSpace(target[p.Name]))); }
private void EnsureValid(IDataErrorInfo validatable, params string[] properties) { if (properties.Any(x => validatable[x] != null)) throw new InvalidOperationException("The object is invalid"); }
/// <summary> /// Check that all items in collection are valid. /// </summary> private void _Validate() { if (App.Current.UIManager.IsLocked || !_dataGrid.IsVisible) return; // Need to stop timer. _StopTimer(); // Enable showing callout. _showCallout = true; // For all items in data grid source collection. foreach (var item in _collection) // If item isn't valid. if ((item is IDataErrorInfo) && !(string.IsNullOrEmpty((item as IDataErrorInfo).Error))) { // Cast item to IDataErrorInfo. var dataObject = item as IDataErrorInfo; // Find first visible column with error. Column column = _GetColumnWithError(dataObject); if (column != null) { // Remeber data object as invalid item. _InvalidItem = dataObject; // If row with this item isn't shown in grid - show it. if (_IsItemVisible(dataObject)) _dataGrid.BringItemIntoView(dataObject); // Set grid's current item on invalid item. // There must be so much invoking, because grid is working async. _dataGrid.Dispatcher.BeginInvoke(new Action(delegate() { _dataGrid.CurrentItem = dataObject; // Show column with wrong property. _dataGrid.Dispatcher.BeginInvoke(new Action(delegate() { _dataGrid.CurrentColumn = column; // Show callout. _dataGrid.Dispatcher.BeginInvoke(new Action(delegate() { _InitCallout(column); _StartTimerSubscribeToEvent(); } ), DispatcherPriority.ContextIdle); }), DispatcherPriority.ContextIdle); }), DispatcherPriority.ContextIdle); // If we found invalid item - stop searching. return; } } }
private void AddErrorMessage(IDataErrorInfo obj) { var properties = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (var property in properties) { if (!String.IsNullOrWhiteSpace(obj[property.Name])) { AddErrorMessage(obj[property.Name]); } } }
public static ICommand AllowWhenNoErrors(this ICommand command, IDataErrorInfo viewModel) { return new DelegateCommand(command.Execute, x => string.IsNullOrWhiteSpace(viewModel.Error) && command.CanExecute(x)); }