/// <summary> /// Add error list to field /// </summary> /// <param name="propertyName"></param> /// <param name="errors"></param> public void AddError(string propertyName, IList <string> errors) { Logger.DebugFormat("Add error messages to property [{0}]...", propertyName); if (!PropertyGetters.ContainsKey(propertyName)) { //Logger.DebugFormat($"[{propertyName}] is not existed."); return; } List <string> errorsTmp; if (!this.errorDic.TryGetValue(propertyName, out errorsTmp)) { errorsTmp = new List <string>(errors); this.errorDic.TryAdd(propertyName, errorsTmp); } else { errorsTmp.AddRange(errors); } // Notify error change this.OnNotifyErrorChanged(propertyName); Logger.Debug($"Add error for [{propertyName}] with [{errors}] successfully."); }
/// <summary> /// Called when [view loaded]. /// </summary> /// <param name="view">The view.</param> protected override void OnViewLoaded(object view) { Logger.Debug("OnViewLoaded..."); base.OnViewLoaded(view); Observable.FromEventPattern <PropertyChangedEventHandler, PropertyChangedEventArgs>( h => this.PropertyChanged += h, h => this.PropertyChanged -= h).Where( x => { if (PropertyGetters.ContainsKey(x.EventArgs.PropertyName)) { this.validatorList.Add(x.EventArgs.PropertyName); return(true); } return(false); }).Throttle(TimeSpan.FromSeconds(0.75)).Subscribe(x => this.ValidateLazy()); Logger.Debug("OnViewLoaded..."); }
/// <summary> /// Get error message of property field /// </summary> /// <param name="propertyName"></param> /// <returns></returns> public IEnumerable GetErrors(string propertyName) { if (!string.IsNullOrWhiteSpace(propertyName)) { if (PropertyGetters.ContainsKey(propertyName)) { List <string> errors; if (this.errorDic.TryGetValue(propertyName, out errors) && !errors.IsNullOrEmpty()) { // Realize a list and send to the OnColumnrror() method this.OnProperyErrors(propertyName, errors); foreach (var error in errors) { yield return(error); } } } } yield break; }
// Common implementation of property reading takes a data ID for a block in the main block tree private void ReadPropertiesInternal <T>(FileStream fs, BTree <Node> subNodeTree, UInt64 dataBid, PropertyGetters <T> g, T target) { var blocks = ReadHeapOnNode(fs, dataBid); var h = blocks.First(); if (h.bClientSig != EbType.bTypePC) { throw new XstException("Was expecting a PC"); } // Read the index of properties var props = ReadBTHIndex <PCBTH>(blocks, h.hidUserRoot).ToArray(); foreach (var prop in props) { if (!g.ContainsKey(prop.wPropId)) { continue; } dynamic val = ReadPropertyValue(fs, subNodeTree, blocks, prop); g[prop.wPropId](target, val); } }
// Common implementation of table reading takes a data ID for a block in the main block tree private IEnumerable <T> ReadTableInternal <T>(FileStream fs, BTree <Node> subNodeTree, UInt64 dataBid, PropertyGetters <T> g, Action <T, UInt32> idGetter, Action <T, Property> storeProp) where T : new() { var blocks = ReadHeapOnNode(fs, dataBid); var h = blocks.First(); if (h.bClientSig != EbType.bTypeTC) { throw new XstException("Was expecting a table"); } // Read the table information var t = MapType <TCINFO>(blocks, h.hidUserRoot); // Read the column descriptions var cols = MapArray <TCOLDESC>(blocks, h.hidUserRoot, t.cCols, Marshal.SizeOf(typeof(TCINFO))); // Read the row index TCROWIDUnicode[] indexes; if (ndb.IsUnicode) { indexes = ReadBTHIndex <TCROWIDUnicode>(blocks, t.hidRowIndex).ToArray(); } else { // For ANSI, convert the index entries to the slightly more capacious Unicode equivalents indexes = ReadBTHIndex <TCROWIDANSI>(blocks, t.hidRowIndex).Select(e => new TCROWIDUnicode { dwRowID = e.dwRowID, dwRowIndex = e.dwRowIndex }).ToArray(); } // Work out which of the columns are both present in the table and have getters defined var colsToGet = cols.Where(c => g.ContainsKey(c.wPropId)).ToList(); // The data rows may be held in line, or in a sub node if (t.hnidRows.IsHID) { // Data is in line var buf = GetBytesForHNID(fs, blocks, subNodeTree, t.hnidRows); var dataBlocks = new List <RowDataBlock> { new RowDataBlock { Buffer = buf, Offset = 0, Length = buf.Length, } }; return(ReadTableData <T>(fs, t, blocks, dataBlocks, cols, colsToGet, subNodeTree, indexes, g, idGetter, storeProp)); } else if (t.hnidRows.NID.HasValue) { // Don't use GetBytesForHNID in this case, as we need to handle multiple blocks var dataBlocks = ReadSubNodeRowDataBlocks(fs, subNodeTree, t.hnidRows.NID); return(ReadTableData <T>(fs, t, blocks, dataBlocks, cols, colsToGet, subNodeTree, indexes, g, idGetter, storeProp)); } else { return(Enumerable.Empty <T>()); } }